给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。
不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。

解题思路

看了一些大佬的解题思路, 大多数都是考虑使用双指针从头到尾遍历.
这样用for循环就会衍生出一个问题: 在遍历列表/数组/切片等的过程中, 此时该列表/数组/切片等的长度会发生变化.
然后有很多大佬直接改用while循环进行解答.
其实, 我们可以换位思考一下: 正向遍历有影响, 我可以反向遍历啊. 想到这个, 题目就很好解了.

  1. 从nums的最后一个开始遍历, 然后与前一个进行对比.
  2. 如果相等, 则删除该位置的数.
  3. 不等, 则继续往前遍历.
  4. 复杂度分析:
    时间复杂度 O(n)
    空间复杂度 O(1)
    1. //双指针 快慢指针
    2. func removeDuplicates(nums []int) int {
    3. n := len(nums)
    4. if n <= 0 {
    5. return n
    6. }
    7. slow := 1 //从一开始
    8. for fast :=1 ; fast <n ; fast++ {
    9. if nums[fast] != nums[fast - 1] { //和自己的上一条比较
    10. //if nums[fast] != nums[slow - 1] { //夹逼解释,通法解读
    11. nums[slow] = nums[fast] //前进一个
    12. slow++
    13. }
    14. }
    15. return slow
    16. }
    image.png
    //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
    }