leetcode第80题:删除有序数组中的重复项 II
题目描述
给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使得出现次数超过两次的元素只出现两次 ,返回删除后数组的新长度。
不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
示例 1:
输入:nums = [1,1,1,2,2,3]
输出:5, nums = [1,1,2,2,3]
解释:函数应返回新长度 length = 5, 并且原数组的前五个元素被修改为 1, 1, 2, 2, 3。 不需要考虑数组中超出新长度后面的元素。
示例 2:
输入:nums = [0,0,1,1,1,1,2,3,3]
输出:7, nums = [0,0,1,1,2,3,3]
解释:函数应返回新长度 length = 7, 并且原数组的前五个元素被修改为 0, 0, 1, 1, 2, 3, 3。不需要考虑数组中超出新长度后面的元素。
整体思路: 这是一个有序的数组,出现重复的数子只会在一起。因为我们找到一个重复数字之后就需要立即删除,导致数组后边的元素会一直发生元素的序号变化,所以我们采用从后往前的方法。使用两个指针,一个指针s,一个指针j,如下图:
设置一个计数器,1.当重复元素超过2时,就将当前元素后面的所有元素向前移一位。移完之后因为之前s指针指向的还是之前的位置,因此要减一。只有发生移位时,数组的长度才会发生变化。2.当两个元素不相同时,就将s指针指向j,并且将计数器重置为1。
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
class Solution {
public:
//将数组当前的这个删除并且移动元素
void move(vector<int>& nums,int pre){
for(int i=pre ; i<nums.size()-1 ; i++){
nums[i]=nums[i+1];
}
}
int removeDuplicates(vector<int>& nums) {
int count=nums.size();//记录nums的元素个数
int s=nums.size()-1; //指针s
while (s>1) //只剩最后一个元素时不用再检查了
{
int renum=1;//计数器,自己就是一个,所以设置为1
for(int j=s-1;j>=0;j--){
if(nums[s]==nums[j]){
renum++;
//每次删除操作时,数组的长度就减 1
if(renum>2){
move(nums,j);
s--;
count--;
}
}else{
s=j;
renum=1;
}
}
}
return count;
}
};
int main(){
vector<int> nums={1,1,1,2,2,3};
Solution s;
cout<<s.removeDuplicates(nums);
}