给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。
不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
示例 1:
给定数组 nums = [1,1,2],
函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2。
你不需要考虑数组中超出新长度后面的元素。
示例 2:
给定 nums = [0,0,1,1,1,2,2,3,3,4],
函数应该返回新的长度 5, 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4。
你不需要考虑数组中超出新长度后面的元素。
首先是自己的解答:
根据提示,使用双指针,也叫快慢指针,index1从首部移动, index2向后移动直到值与index1不同,则将 index2及之后的元素移动到index1+1的位置,重复直至index2抵达末位,然后返回的长度为:index1+1,因为index1是索引,比当前不重复元素少一。
代码如下:
//26. 删除排序数组中的重复项 //原地删除重复元素,并且返回结果的长度int //双指针 int removeDuplicates(vector<int>& nums) { if (nums.size() < 2) return nums.size(); //排序 sort(nums.begin(), nums.begin() + nums.size()); int idx1 = 0, idx2 = 1; while (idx2 < nums.size()) { while (idx2 < nums.size() && nums[idx1] == nums[idx2]) idx2++; if (idx2 == nums.size()) return idx1 + 1; for (int i = idx1+1; i < idx2; i++) { nums[i] = nums[idx2]; } //test for (auto val : nums) { cout << val << "\t"; } cout << endl; idx1++; idx2++; } return idx1 + 1; }
虽然提交后通过了,但是时间、空间效率很差。
看解答后,发现只要把index2处不重复的元素复制到index1+1即可,减少元素的移动次数,代码如下:
int removeDuplicates(vector<int>& nums) { if (nums.size() < 2) return nums.size(); //sort sort(nums.begin(), nums.begin() + nums.size()); int idx1 = 0, idx2 = 1; while (idx2 < nums.size()) { if (nums.at(idx1) != nums.at(idx2)) { //如果不等,把idx2的元素放到idx1++的位置 idx1++; nums[idx1] = nums[idx2]; } //如果idx2 与 idx1 相等,则j++ idx2++; } return idx1 + 1; }
小结:
刷题后,多看题解,最好敲一遍学习学习。
原文:https://www.cnblogs.com/zyk1113/p/14001571.html