leetcode 26. Remove Duplicates from Sorted Array
leetcode 27. Remove Element
这两道题目是同样的题目。
解决办法也是用双指针。
重要的事情说三遍,排序排序排序看看是不是有对解决问题有改善。
然后既然是双指针,就得向用同向还是双向。
对于移除重复元素,以及之前的subarray等。都是要用同向。
因为重复元素一个指针指向头,一个指向尾部。头部要向尾部靠拢。
subarray也是一样。subarray中第一个不是1或者1的元素。
也就是他们里面都有重复元素,要去重或者要找多少个子序列。
既然这样,就得用双向指针的模板了
上模板
int j = 1;
for(int i = 0;i<n;i++){
j = max(i+1, j)// 确保j比i大
while(j < n && j, i 不满足要求的条件)
j++;
if(退出while的原因1)
xxxx
if(退出while的原因2)
xxxxx
}
26. Remove Duplicates from Sorted Array为例子。
i指向的是重复元素的第一个位置,
j指向的是第一个不等于i的元素
平常的时候,就用 num[i+1] = num[j] 来做个废操作。这个也是为了以后要填坑(重复元素的坑)用的。
当i和j之间有很多重复元素的时候,这个num[i+1] = nun[j] 的填坑作用就出来了。
填完坑以后, nums[i+1] == nums[j]
当i 向后移动一个位置, 就又发现了当前的元素和nums[j]重复,j继续后移动。
套用双指针公式后的代码如下。 这里最重要的另一个思想就是 nums[i+1] == nums[j].
这样让j 往后移动。
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
// 看到数组先想想能不能排序。。。重要的问题说三遍
// 同向双指针来处理这个问题
// i指向的是前一个uniq 数字
// j指向下一个uniq 数字
// 然后把j指向的数字覆盖到i+1指向的位置
//套用模板了
int j = 1;
int i;
for( i = 0;i<nums.size();i++){
j = max(j, i+1);
while(j < nums.size() && nums[j]==nums[i]){
j++;
}
if(j >= nums.size())
break;
nums[i+1] = nums[j];
}
return i+1;
}
};
相同的27. Remove Element, 为了让元素向后以后,我也用了一个办法。
填完别人的坑以后,也得把自己的坑填成要移除的元素。让后面的元素来继续填坑。
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
这个就是我说的,我填完前面的坑了,也得把自己的坑填成重复元素。
这样j就能往后移动。知道j达到最后的位置。
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
//和之前的移除重复的元素一样。同向双指针
// 先排序, 这样才能把相投的凑一块。
// i 指向的是 val, j指向的是不同于i的val
//然后把 j指向的元素覆盖i指向的元素
sort(nums.begin(), nums.end());
int j = 1;
int i;
for(i = 0;i < nums.size(); i++){
if(nums[i] != val)
continue;
j = max(j, i+1);
while(j < nums.size() && nums[j] == nums[i])
j++;
if(j == nums.size())
break;
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
return i;
}
};