难度中等
给定一个增序排列数组 nums
,你需要在 原地 删除重复出现的元素,使得每个元素最多出现两次,返回移除后数组的新长度。
不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
一开始没有看题解,一看额外空间是O(1),知道了是在原有数组上做文章,想法是用一个快慢指针,快指针统计当前数字有多少个重复的次数,慢指针表示新的数字填入的位置,如果快指针统计大于2,则填入两个快指针指向的数,否则填一个。当快指针遍历完原数组后,返回慢指针指向的元素序号就行了。代码如下:
/**
* * @param {number[]} nums
* * @return {number}
* */
var removeDuplicates = function(nums) {
let i=0;
let j=0;
while(j<nums.length)
{
let k=nums[j];
let p=1;
while(j+1<nums.length&&nums[j+1]==k)
{
j++;
p++;
}
j++;
if(p>=2)
{
nums[i]=k;
nums[i+1]=k;
i+=2;
}else
{
nums[i]=k;
i+=1;
}
}
return i;
};
结果一看执行用时:120 ms, 在所有 JavaScript 提交中击败了9.20%的用户,于是看题解,发现对于处理好的数组有个规律,那就是元素最多不重复两次以上,对于i位置的元素它和i-2位置的元素一定不一样,而处理后的数组元素排序和原数组相同,而数组的前两个元素因为没有i-2位置的限制,所以前两个数字是一定填入新数组的,所以我们从第三个元素开始遍历,还是快慢指针,但是这次不需要统计出现的次数了而是直接比较他和慢指针前两位的数字是否一致,不一致则填入。代码如下:
/**
* * @param {number[]} nums
* * @return {number}
* */
var removeDuplicates = function(nums) {
if(nums.length<=2)
return nums.length;
let i=2;
for(let j=2;j<nums.length;j++)
{
if(nums[j]!=nums[i-2])
nums[i++]=nums[j];
}
return i;
};