给你一个 非严格递增排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。
考虑 nums 的唯一元素的数量为 k ,你需要做以下事情确保你的题解可以被通过:
更改数组 nums ,使 nums 的前 k 个元素包含唯一元素,并按照它们最初在 nums 中出现的顺序排列。nums 的其余元素与 nums 的大小不重要。
返回 k 。
判题标准:
系统会用下面的代码来测试你的题解:
int[] nums = […]; // 输入数组
int[] expectedNums = […]; // 长度正确的期望答案
int k = removeDuplicates(nums); // 调用
assert k == expectedNums.length;
for (int i = 0; i < k; i++) {
assert nums[i] == expectedNums[i];
}
如果所有断言都通过,那么您的题解将被 通过。
示例 1:
输入:nums = [1,1,2]
输出:2, nums = [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]
解释:函数应该返回新的长度 5 , 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4 。不需要考虑数组中超出新长度后面的元素。
解答:用快慢指针解决
func removeDuplicates(nums []int) int {
// 特殊情况:当数组长度为1时,此时不重复元素长度为1
if len(nums) == 1 {
return 1
}
// 在数组首部添加两个快慢指针,慢指针指向0,快指针指向1
// 慢指针负责存储不重复元素(慢指针及其左侧都是不重复元素),快指针负责寻找不重复元素
slow := 0
fast := 1
// 在快指针越过数组边界之前向前寻找不重复元素,判断快指针找到的元素nums[fast]与慢指针元素nums[slow]是否相等:
for fast < len(nums) {
if nums[slow] != nums[fast] {
// 不相等,说明找到了新的不重复元素
// slow向右移动一位来存储该不重复元素
slow++
// 将该nums[fast]值更新到nums[slow]中
// 优化:如果slow和fast紧挨着,比如数组中不存在重复元素,则slow+1和fast就是同一个,此时的赋值操作是不必要的;因此可以判断fast-slow>1时才进行赋值
nums[slow],nums[fast] = nums[fast],nums[slow]
// fast继续向后寻找
fast++
} else {
// 相等,说明是重复元素,跳过,fast继续向后寻找
fast++
}
}
// 当fast越界,此时慢指针slow的位置就是前面不重复数组部分的最后一个元素的索引
return slow + 1
}
本文介绍了一种使用快慢指针的方法来解决给定非严格递增数组中删除重复元素的问题,同时保持元素的相对顺序,最后返回唯一元素个数及处理后的数组结构。
302

被折叠的 条评论
为什么被折叠?



