今天总结一下LeetCode上简单题26、27。放在一起说是因为这两个题目比较相似
首先我们看一下26题
思路一
拿到这个题目的第一个想法是使用两个数组,第一个数组为原数组,第二数组为目标数组。目标数组首先存第一个数组值,用原数组去比对。如果原数组中的一个数和目标数组的已有的值没有一个相同则存入目标数组。但是这个想法虽然简单粗暴,但是实现起来比较麻烦。而且时间成本上也会很高。另外本题还有一个额外的要求就是 你必须原地修改输入数组,并在使用O(1)的额外空间条件下完成
思路二
我想的第二个思路是,既然是升序排列的数组。那么我就用一个max值去存储最大值。先用max值存储数组中的第一个值。然后从数组的第二个值开始比较,如果这个位置的值和max值一样大,那么将该位置的值置空。接着继续向后比。如果这个位置的值比max值大,那么将max值置为该值,并继续重复之前的步骤直到遍历完整个数组。这时数组中的重复值已经被删除了,而接下来要做的就是将位置交换。第二次遍历数组,将空值和第一个不为空的值交换。以此类推。
思路二的参考代码
。
// 这是我在DEV上写的,如果想要提交到leetcode上还需要做出一些更改;
//
int n;
cin>>n;
int nums[n];
int length=0;
for(int i=0; i<n; i++)
{
cin>>nums[i];
}
int max=nums[0];
for(int i=1;i<n;i++)
{
if(nums[i]>max)
{
max = nums[i];
}
else
{
nums[i]=999;
}
}
for(int i=0;i<n;i++)
{
if(nums[i]==999)
{
for(int j = i ;j<n;j++)
{
int temp=0;
if(nums[j]!=999)
{
temp=nums[i];
nums[i]=nums[j];
nums[j]=temp;
break;
}
}
}
}
for(int i=0;i<n;i++)
{
if(nums[i]!= 999)
{
length++;
}
}
cout<<length;
;
最后提交后的结果为80分
思路三
这是我在leetcode评论区里面学到的思路非常巧妙,我们直接上代码
// Leetcode;
//
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
if(nums.size()<2) return nums.size();
int j = 0 ;
for(int i = 1;i<nums.size();i++)
{
if(nums[j]!=nums[i]) nums[++j]=nums[i];
}
return ++j;
}
};;
首先判断数组长度,如果小于等于1那么直接返回就好了。
接着遍历数组,先跟数组中的第一个值相比,如果不相等,则将数组中的第二个值改为数组遍历到的值。接着将比较值也进行修改,改为数组中的第二个值,进行比较。思路非常巧妙,代码简洁高效。
需要注意的点
1.注意nums数组判断大小的方法是 nums.size();而不是sizeof(nums)坑了我好久,这样书写会出现越界问题
2.注意审题,题目要求的是原地修改,不可利用新的数组。
接着看一下27题
做完26题的第二天我打算去做第27题,看到题目的一瞬间我就想到了前一天做的题目的解法。
看到题目是不是很眼熟,甚至连需要比较的值都不需要更新。这次的代码非常快的就写出来了。那我们直接上代码。
代码展示
// codeblock
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int j=0;
for(int i=0;i< nums.size();i++)
{
if(nums[i] != val ) nums[j++]=nums[i];
}
return j;
}
};;
直接通过并超过百分百的提交记录。