这是我参与2022首次更文挑战的第18天,活动详情查看:2022首次更文挑战
题目描述
提供一个有序的整数数组,请你直接在数组中删除重复出现的数字,最终实现每个数字只出现一次,然后返回数组的新长度。
举个例子:
数组:[1,1,3]
返回: 2 ([1,3])
数组:[1,1,1,3,3,4,5,5,6,6]
返回: 5 ([1,3,4,5,6])
补充: 不能使用额外的数组空间,需要在原来的数组上做改变,可以使用额外的常量空间。
思路分析
第一种方法
既然在原来的数组上做修改,去重,那么就可以在遍历数组的时候,如果发现前一个和当前的遍历的数是相等的,则把它删除掉(使用splice方法),然后把索引减一继续遍历(因为后面的往前移动了)
然后不需要对数组第一个对元素做判断,直接跳过。
代码如下:
/**
* @param {number[]} nums
* @return {number}
*/
var removeDuplicates = function (nums) {
for (let i = 0; i < nums.length; i++) {
if (i === 0) continue
else {
if (nums[i - 1] === nums[i]) {
nums.splice(i, 1)
i = i - 1
}
}
}
return nums.length
};
第二种方法
第一种方法是可以解决问题,但是耗时有点长,下面咱们来看看第二种方法。
这个是利用双索引实现的,只使用了2个常数的额外空间,一个是快索引(默认值是1),一个是慢索引(默认值是1),快索引每次遍历都加一,如果快索引的元素和前一个快索引的元素不相等,则把它赋值给慢索引,替换当前慢索引的元素,然后慢索引加一,然后继续遍历
当快索引遍历结束后,则慢索引指向的位置就是去重后的数字。
最后返回慢索引的位置即可。
代码如下:
/**
* @param {number[]} nums
* @return {number}
*/
var removeDuplicates = function (nums) {
if (nums.length === 0) return 0
let fast = 1, slow = 1;
while (fast < nums.length) {
if (nums[fast] !== nums[fast - 1]) {
nums[slow] = nums[fast]
slow++
}
fast++
}
return slow
};
两种方法,第一种方法比较容易想到,但是时间复杂度高。
推荐第二种方法。