LeetCode第26题删除有序数组中的重复项

64 阅读2分钟

题目

给你一个 非严格递增排列 的数组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已按 非严格递增 排列

思路

  1. 双指针解题,定义两个指针finder和last,移动指针,比较两个指针指向的值
  2. finder指针一直移动,直到数组末尾;last指针只有找到不同值时才移动
  3. 两层循环,外层循环移动last指针,内层循环移动finder指针,外层循环退出条件为last指针指向数组末尾;内层循环退出条件,两个指针指向不同的值
  4. 找到不同值时,将不同值赋值给当前last指针指向的下一个数值,同时移动last指针
  5. 最终返回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
}