leetcode的第80题删除有序数组中的重复项,可以使用快慢指针解决。
题目要求原地删除重复出现的元素,使得出现次数超过两次的元素只出现两次 ,返回删除后数组的新长度。
首先,由于要求相同元素只能出现两次,并且所给数组相同元素都是连续的,根据抽屉原理,如果数组只包含一个元素,无需删除,返回数组长度即可;若数组只包含两个元素,那只有两种情况,要么两个元素相同,要么两个元素不同。当两个元素不同时,显然满足;两个元素不同时,由于只有两个元素,必然也满足;所以当数组长度小于等于2时,直接返回数组长度即可。
if(nums.size() <=2 ) return nums.size();
然后分析数组长度大于2的情况:
(1)首先,我们设置快慢指针的位置:
int slow=2,fast=2;
为什么设置在2的位置,因为已经经过if判断,数组长度显然大于等于3;
slow用于保存fast的元素,fast用于检测元素是否已经重复超过两次;
slow所在位置的左边是已经删除过的数组,slow所在位置是待更新的位置,fast通过对比其所在位置的元素和slow-2的元素是否相同来决定是否更新slow的元素(为什么是slow-2的位置,因为slow左边的元素如果是已经有两个相同元素了,而此时fast的元素与其相同,那么就不更新,即slow已经保存了两个相同元素,剩余相同的元素删除即可)
(2)其次,找到循环判断条件:
while(fast<n)
(3)接着,要进行删除操作,那么该如何判断删除呢,因为要求相同元素只能保留两个,并且相同元素都是连续的,那么只需要判断fast位置处的元素和(slow-2)位置处的元素是否相等就可以。如果相同,那就只更新fast,slow不变,等待更新;如果不同,那就说明从fast开始的新元素还可以保存到slow:
if(nums[fast]!=nums[slow-1]) nums[slow]=nums[fast]; ++slow;
(4)最后,无论更不更新slow,fast都要继续检查新元素,++fast;
给出此题的力扣代码:
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
int slow=2,fast=2,n=nums.size();
if(n<=2) return n;
while(fast<n){
if(nums[fast]!=nums[slow-2]){
nums[slow]=nums[fast];
++slow;
}
++fast;
}
return slow;
}
};
此题的弱化版本,就是力扣的第26题删除有序数组中的重复项