题干
给你一个有序数组 nums ,请你 [原地] 删除重复出现的元素,使得出现次数超过两次的元素只出现两次 ,返回删除后数组的新长度。
不要使用额外的数组空间,你必须在 原地修改输入数组 并在使用 O(1) 额外空间的条件下完成。
题解--双指针
本题和LeetCode 26.删除有序数组中的重复项思路类似,同样使用双指针。区别是本题要求不保留出现次数超过两次的数,而LeetCode26要求不保留出现次数超过一次的数。设置快慢两个指针(fast和slow),slow始终指向已经检查过的数组边界,slow之前的数组满足出现次数超过两次的元素只出现两次的条件,fast始终指向当前要检查的元素。对于每一个fast指向的元素,我们需要检查它能不能够被放在slow指向的位置上,如果它可以被放在slow的位置上,那么它一定满足nums[fast] != nums[slow-2],否则同一个元素就有可能会出现三次了。当满足nums[fast] != nums[slow-2],就使得nums[slow] = nums[fast],并将slow往后挪动,即,数组边界向后移动;而当它不满足这个条件,就需要跳过这个数,不把数组边界向后移动,并把fast向后移动去检查下一个数是否满足条件。
func removeDuplicates(nums []int) int {
// 处理边界情况,当数组长度<2,直接返回数组长度即可
n := len(nums)
if n < 2 {
return n
}
slow, fast := 2, 2
for fast < n {
// 检查nums[fast]是否可以被放到slow指向的位置
if nums[slow-2] != nums[fast] {
nums[slow] = nums[fast]
slow++
}
fast++
}
return slow
}