题目
分析 && 代码
这也是复习的时候感慨的一道好题目,特此记录一下。
题目很简单,要求in place,也不算难,按照我的想法记录一下前一个出现的数字,因为有序,如果之后遇到了相同的,就把后面的删了。
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
if (nums.size() <= 1) return nums.size();
// 前一个出现的数字
int num = nums[0];
for (auto it = ++nums.begin(); it != nums.end();) {
// 重复数字 删除即可
// 注意原来的迭代器会失效,不用自增
if (*it == num) {
nums.erase(it);
}
// 如果不重复 就更新num 同时自增迭代器
else {
num = *it;
it++;
}
}
return nums.size();
}
};
交了一发
但是好慢啊,分析一波慢的原因就是在于这种方式会不断的调整vector的结构,因为删除一个元素,vector是需要调整的,当vector很大的时候,这种反复的调整无疑是灾难性的。
能不能不删除呢,可以但是就需要存在新的容器或者数组,但题目要求了in place。
但是注意题目返回的值是int,表示的是最后保留的数组的长度,这就暗示我们可以不开额外vector而是直接利用这个vector,然后记录下去重的数据的长度,至于后面的数字可以不管他。实现的方法就是用一个计数器记住当前去重的数组最后一个元素的下标,如果不同就赋值到数组中它的下一个位置,来看代码就明白了。
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
if (nums.size() <= 1) return nums.size();
int len = 1;
for (int i = 1; i < nums.size(); ++i) {
if (nums[i] != nums[len - 1]) {
nums[len] = nums[i];
len++;
}
}
return len;
}
};