# 删除排序数组中的重复项
力扣🔗: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]);
}
# 解题思路
- 设置快慢双指针
fast
和slow
,分别指向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
}