# 删除排序数组中的重复项

力扣🔗:https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array (opens new window)

# 题目

给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。

不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。

示例 1:

给定数组 nums = [1,1,2], 

函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2。 

你不需要考虑数组中超出新长度后面的元素。

示例 2:

给定 nums = [0,0,1,1,1,2,2,3,3,4],

函数应该返回新的长度 5, 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4。

你不需要考虑数组中超出新长度后面的元素。

说明:

为什么返回数值是整数,但输出的答案是数组呢?

请注意,输入数组是以**「引用」**方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。

你可以想象内部操作如下:

  // nums 是以“引用”方式传递的。也就是说,不对实参做任何拷贝
int len = removeDuplicates(nums);

// 在函数里修改输入数组对于调用者是可见的。
// 根据你的函数返回的长度, 它会打印出数组中该长度范围内的所有元素。
for (int i = 0; i < len; i++) {
    print(nums[i]);
}

# 解题思路

  • 设置快慢双指针 fastslow,分别指向 nums 的第二位和第一位。
  • 比较两指针指向的值。如果 nums[fast] === nums[slow],表示是重复项,往后移动快指针;如果 nums[fast] !== nums[slow],表示是下一个非重复项,此时检查两指针距离是否超过 1,若超过则更新 nums[slow + 1] = nums[fast],随后向后移动两指针。
  • 重复上一步操作直到快指针到达 nums 末尾,此时已将所有非重复项按序排列在该数组左端,返回 slow + 1,也就是非重复项组成的长度即可。

# 代码实现

/**
 * @param {number[]} nums
 * @return {number}
 */
function removeDuplicates(nums) {
  let slow = 0 // 慢指针
  let fast = 1 // 快指针

  while (fast < nums.length) {
    if (nums[slow] === nums[fast]) {
      // 快指针跳过重复项
      fast++
    } else {
      if (fast - slow > 1) {
        // 如果存在重复项,则修改慢指针后面一项的值为快指针指向的值
        nums[slow + 1] = nums[fast]
      }
      slow++
      fast++
    }
  }

  return slow + 1
}