题目
给你一个 非严格递增排列 的数组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 。不需要考虑数组中超出新长度后面的元素。
提示:
1 <= nums.length <= 3 * 10^4^-10^4^ <= nums[i] <= 10^4^nums已按 非严格递增 排列
思路
- 双指针解题,定义两个指针finder和last,移动指针,比较两个指针指向的值
- finder指针一直移动,直到数组末尾;last指针只有找到不同值时才移动
- 两层循环,外层循环移动last指针,内层循环移动finder指针,外层循环退出条件为last指针指向数组末尾;内层循环退出条件,两个指针指向不同的值
- 找到不同值时,将不同值赋值给当前last指针指向的下一个数值,同时移动last指针
- 最终返回last+1
代码
func removeDuplicates(nums []int) int {
if len(nums) == 0 {
return 0
}
//采用双指针解题,finder指针一直移动,last指针只有找到不同值时移动
finder, last := 0, 0
//last移动到数组末尾
for last < len(nums)-1 {
//找到不同值退出循环
for nums[finder] == nums[last] {
finder ++
//finder移动到数组末尾,返回
if finder == len(nums) {
return last + 1
}
}
//找到不同值,替换数组重复值
nums[last+1] = nums[finder]
last++
}
return last + 1
}