题目描述
给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。
不要使用额外的数组空间,你必须在原地修改输入数组并在使用 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。
你不需要考虑数组中超出新长度后面的元素。
思路1
最蠢的办法,就是每次扫描碰到遇到重复元素,就将后面元素前移一位
代码实现
int removeDuplicates(vector<int>& nums) {
int len = nums.size();
if(len == 0){return 0;}
if(len == 1){return 1;}
int tmp = nums[0];
int count = 1, i = 1;
int move = 0; //记录移动次数,则后面move个是无用的
while(i < len - move){
if(tmp == nums[i]){
for (int j = i; j < len - 1; ++j) //后面所有元素前移
{
nums[j] = nums[j+1];
}
++move;
}
else{
tmp = nums[i]; //保存现在需要查看是否还有重复的元素
++i;
++ count;
}
}
return count;
}
思路2
使用两个指针,tail用于向后扫描判断是否元素重复,head指针用于指示当前不同元素需要放的位置,head只有在元素不同时才加1
代码实现
int removeDuplicates(vector<int>& nums){
int len = nums.size();
if(len == 0) {return 0;}
int head = 0;
int tail = 0;
while(tail < len - 1){
//当前元素和后一个不同,head位置保存那个不同的元素
if(nums[tail] != nums[tail+1]){
nums[head++] = nums[tail++];
}
//相同就尾指针加1,直到不同为止,直接保存到head位置,避免移动
else{
++tail;
}
}
//最后一个不同元素是没有保存的,因为相同会一直++tail,而且每次head位置
//保存的是当前相同元素最后一个位置(下一个元素就不同了)
nums[head++] = nums[len - 1];
return head;
}
思路3
每次记录需要比较的元素tmp和不重复元素个数count,遍历数组,当tmp和当前扫描元素不同,则保存当前元素到count位置,同时count计数+1,并更新tmp为当前元素
代码实现
int removeDuplicates(vector<int>& nums){
int len = nums.size();
if(len == 0){return 0;}
int count = 1;
int tmp = nums[0];
for(int i = 1; i < len; ++i){
if(tmp != nums[i]){
nums[count] = nums[i];
++count;
tmp = nums[i];
}
}
return count;
}