题目描述
【leetcode】26. 删除排序数组中的重复项(Remove Duplicates from Sorted Array))
给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。
不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。
第一次解答
思路:
输入是存放在连续内存
为了最小的减少内存拷贝操作,
应该从后往前删除重复元素
由于数组已经排序过,只需要判断相邻位置即可
删除操作可以是用vector自带的
也可以自己挨个移动每个元素
注意:
nums.size() == 0
nums.size() == 1
test case:
[1,1,2]
[0,0,1,1,1,2,2,3,3,4]
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
if(nums.size() == 0 || nums.size() == 1)
return nums.size();
int nums_size = nums.size();
for(int i = nums.size()-2; i>=0; --i){
if(nums[i] == nums[i+1])
{
--nums_size;
for(int j=i+1; j<nums_size; ++j)
{
nums[j] = nums[j+1];
}
}
}
return nums_size;
}
};
结果:
第二次解答
解答一的用时也太长了,因为要拷贝很多次。
看到提示用双指针,突然想到也可以从前往后遍历,且题目要求只能用O(1)个额外内存,但指针不算内存吧?且有限个额外内存,也是O(1)。
从后往前遍历的缺点是:每次删除一个元素,该元素后的所有元素都需要移动,排在较后面的元素需要移动多次。
从后往前遍历的用法,可能是在从后面某个位置连续往前删除元素时,比较有优势吧。
从前往后遍历的优点是:遍历到某个元素后,该元素之前的所有元素位置均固定,不需要再次移动,相当于元素要么不移动,一移动就移动到最终该在的位置。
思路:
从前往后遍历,双指针,快指针和慢指针
快指针>慢指针,快指针的作用是不断往后遍历,直到遇到与慢指针不同的元素,
然后把元素赋值给慢指针,接着慢指针+1
这里用索引当指针,也一样。
删除操作可以是用vector自带的
也可以自己挨个移动每个元素
注意:
nums.size() == 0
nums.size() == 1
nums最后一个元素,或者倒数第二个元素
test case:
[1,1,2]
[0,0,1,1,1,2,2,3,3,4]
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
if(nums.size() == 0 || nums.size() == 1)
return nums.size();
int index_slow = 0;
int index_fast = 1;
for(int index_fast = 1; index_fast<nums.size(); ++index_fast){
if(nums[index_slow] != nums[index_fast]){
++index_slow;
nums[index_slow] = nums[index_fast];
}
}
return index_slow+1;
}
};
结果: