一、题目再解读
原题题干
1.给你一个 非严格递增排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。
2.考虑 nums 的唯一元素的数量为 k。去重后,返回唯一元素的数量 k。
3.nums 的前 k 个元素应包含 排序后 的唯一数字。下标 k - 1 之后的剩余元素可以忽略。
核心规则(抓重点)
原地修改:不能新建数组,只能在原数组上改,空间复杂度O(1)
返回值:返回移除后的数组长度k,原数组前k个元素为有效元素
顺序有关:有效元素顺序不可以打乱,这是前后指针优化的关键
无需处理k之后的元素,系统不会校验 示例演示
输入: nums = [1,1,2]
输出: 2, nums = [1,2,_]
解释: 函数应该返回新的长度 2 ,并且原数组 nums 的前两个元素被修改为 1, 2 。不需要考虑数组中超出新长度后面的元素。
解释:返回新长度2,数组前两位为有效元素,后续元素可忽略
二、新手踩坑实录(我的错误代码复盘)
一遍过 没有错 嘻嘻
三、最优解法:快慢双指针法(空间O(1),时间O(n))
解法思路
利用快慢双指针,头尾指针从数组开头向结尾遍历,核心逻辑:
数组是有序的 → 重复元素一定挨在一起
-
慢指针 slow:指向新数组最后一个有效位置
-
快指针 fast:遍历数组,找不重复的新元素
-
发现不一样 → 慢指针前进一步,把快指针的值覆盖过来
-
最后
slow + 1就是新数组长度
var removeDuplicates = function(nums) {
// 空数组直接返回0
if (nums.length === 0) return 0;
let slow = 0;
// 慢指针:保存不重复元素
for (let fast = 1; fast < nums.length; fast++) {
// 快指针遍历
// 发现不重复元素
if (nums[fast] !== nums[slow]) { slow++;
// 慢指针前进 nums[slow] = nums[fast];
// 覆盖赋值
} }
// 新数组长度 = slow + 1
return slow + 1; };
四、复杂度分析
时间复杂度:O(n),数组仅遍历一次,前后指针移动总次数不超过2n
空间复杂度:O(1),仅用了两个指针变量,无额外数组空间开销,完全符合题目要求
五、结语
和上次的题目知识点很像,没什么难度,嘿嘿,继续加油