给你一个有序数组 nums
,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。
不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
解题思路
看了一些大佬的解题思路, 大多数都是考虑使用双指针从头到尾遍历.
这样用for循环就会衍生出一个问题: 在遍历列表/数组/切片等的过程中, 此时该列表/数组/切片等的长度会发生变化.
然后有很多大佬直接改用while循环进行解答.
其实, 我们可以换位思考一下: 正向遍历有影响, 我可以反向遍历啊. 想到这个, 题目就很好解了.
- 从nums的最后一个开始遍历, 然后与前一个进行对比.
- 如果相等, 则删除该位置的数.
- 不等, 则继续往前遍历.
- 复杂度分析:
时间复杂度 O(n)
空间复杂度 O(1)//双指针 快慢指针
func removeDuplicates(nums []int) int {
n := len(nums)
if n <= 0 {
return n
}
slow := 1 //从一开始
for fast :=1 ; fast <n ; fast++ {
if nums[fast] != nums[fast - 1] { //和自己的上一条比较
//if nums[fast] != nums[slow - 1] { //夹逼解释,通法解读
nums[slow] = nums[fast] //前进一个
slow++
}
}
return slow
}
//80.删除有序数组中的重复项2 //快慢指针,k==2时,通法解答,和上面其实一样 func removeDuplicates(nums []int) int { n := len(nums) if n <= 2 { return n } slow , fast := 2, 2 for fast <n { if nums[fast] != nums[slow-2] { //核心语句,夹逼准则,只能有a-0,a-1个相等a-2个就超了 nums[slow] = nums[fast] slow++ } fast++ } return slow }