题干:
给你一个 非严格递增排列 的数组 nums
,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums
中唯一元素的个数。
考虑 nums
的唯一元素的数量为 k
,你需要做以下事情确保你的题解可以被通过:
- 更改数组
nums
,使nums
的前k
个元素包含唯一元素,并按照它们最初在nums
中出现的顺序排列。nums
的其余元素与nums
的大小不重要。 - 返回
k
。
首先:要明白什么是非严格递增排列。如:[1,2,2,3,4,4,5]这就是非严格递增。
所以这个前提下,只有相邻元素才可能重复,只判断相邻元素是否重复就行了。
解法:快慢指针
func removeDuplicates(nums []int) int {
if len(nums) == 0 {
return 0
}
k := 1
for i := 1; i < len(nums); i++ {
if nums[i] != nums[k-1] {
nums[k] = nums[i]
k++
}
}
return k
}
解析:
-
初始化指针:
k
是一个慢指针,用于记录唯一元素的位置。i
是一个快指针,用于遍历数组。
-
遍历数组:
- 从
i = 1
开始遍历数组nums
。 - 对于每个元素
nums[i]
,检查它是否与前一个唯一元素nums[k-1]
不同。
- 从
-
处理唯一元素:
- 如果
nums[i]
不等于nums[k-1]
,说明nums[i]
是一个新的唯一元素。 - 将
nums[i]
赋值给nums[k]
,并将k
增加 1。
- 如果
-
返回结果:
- 遍历结束后,
k
的值就是唯一元素的数量。 - 返回
k
。
- 遍历结束后,
具体示例
假设 nums = [1, 2, 2, 3, 4, 4, 5]
,执行上述算法的过程如下:
-
初始状态:
i = 1
,k = 1
,nums = [1, 2, 2, 3, 4, 4, 5]
-
第一次遍历:
nums[i] = nums[1] = 2
nums[k-1] = nums[0] = 1
- 因为
2 != 1
,所以nums[k] = 2
,k++
,nums = [1, 2, 2, 3, 4, 4, 5]
-
第二次遍历:
nums[i] = nums[2] = 2
nums[k-1] = nums[1] = 2
- 因为
2 == 2
,所以跳过。
-
第三次遍历:
nums[i] = nums[3] = 3
nums[k-1] = nums[1] = 2
- 因为
3 != 2
,所以nums[k] = 3
,k++
,nums = [1, 2, 3, 3, 4, 4, 5]
-
第四次遍历:
nums[i] = nums[4] = 4
nums[k-1] = nums[2] = 3
- 因为
4 != 3
,所以nums[k] = 4
,k++
,nums = [1, 2, 3, 4, 4, 4, 5]
-
第五次遍历:
nums[i] = nums[5] = 4
nums[k-1] = nums[3] = 4
- 因为
4 == 4
,所以跳过。
-
第六次遍历:
nums[i] = nums[6] = 5
nums[k-1] = nums[3] = 4
- 因为
5 != 4
,所以nums[k] = 5
,k++
,nums = [1, 2, 3, 4, 5, 4, 5]
最终返回 k = 5
,nums
的前五个元素为 [1, 2, 3, 4, 5]
,符合题目要求。
通过上述分析,我们可以看到,由于数组的非严格递增性质,我们只需要比较当前元素 nums[i]
和前一个唯一元素 nums[k-1]
,而不需要比较更早的元素。