题目描述【来自-右侧点击力扣】:
给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。
不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
目标是:原地删除数组 重复出现的元素,每个元素只能出现一次。
返回值:删除后的数组的新长度。
注意点:
1. 数组是有序的
2. 数组里面的每个元素最终只有一个
3. 不能声明新的数组,必须修改原数组
1. 解法1,暴力解法
逻辑是:for循环 遍历,每个元素和下一个元素进行比较,如果说相等,就删除当前索引的元素。
技术点:1. while和for循环 2. 数组的splice方法(删除元素的索引,删除几个)
var removeDuplicates = function (nums) {
for (var i = 0; i < nums.length; i++) {
while (nums[i] === nums[i + 1]) {
nums.splice(i, 1)
}
}
console.log(nums)
return nums.length
}
console.log(removeDuplicates([1, 2, 3, 4, 4, 4, 5, 5, 5]))
原有的写法和上面几乎一模一样,但是while 的地方写成了 if,就会无法完全实现。
能够通过的是[]1,2,3,3,4];
不能够通过的用例[1,2,3,3,3,4]; 只要重复的项大于等于3个,就会报错。
var removeDuplicates = function (nums) {
for (var i = 0; i < nums.length; i++) {
if (nums[i] === nums[i + 1]) {
nums.splice(i, 1)
}
}
console.log(nums)
return nums.length
}
console.log(removeDuplicates([1, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5]))
原因在于,if写法,如下表格
i | i+1 | nums[i] | nums[i+1] | nums原数组 splice以后 |
0 | 1 | 1 | 2 | |
1 | 2 | 2 | 3 | |
2 | 3 | 3 | 3 | [1,2,3,3,4,4,4,5,5,5] |
注意,上面一行执行,数组少了一个元素,索引对应的值会变化。 | ||||
3 | 4 | 3 | 4 | 这里不会发生变化,跳过了第二个重复的3,问题出在这里 |
而用while
i | i+1 | nums[i] | nums[i+1] | nums原数组 splice以后 |
0 | 1 | 1 | 2 | |
1 | 2 | 2 | 3 | |
2 | 3 | 3 | 3 | [1,2,3,3,4,4,4,5,5,5] |
注意,上面一行执行,数组少了一个元素,索引对应的值会变化。但是,while和if最大的差别是,while如果条件满足,仍旧会继续循环,不会马上跳出循环。索引 i 依旧为2,索引i+1 依旧为3,对应的值仍旧是3和3,再次执行删除操作。 |
解法2: 数组设置两个指针。
其实我只学了js,没学过其它语言类似java和C语言,对于双指针这个解法有点懵,只能一个值一个值带进去理解代码。参见下面代码、表格和分析。
var removeDuplicates = function (nums) {
let i = 0
for (let j = 0; j < nums.length; j++) {
if (nums[i] != nums[j]) {
i++
nums[i] = nums[j]
}
}
return i + 1
}
console.log(removeDuplicates([1,2,3,4,4,5]))
i | j | nums[i] | nums[j] | i++后的 i | i++后的 nums[i] | nums 替换后的数组 |
0 | 0 | 1 | 1 | 不执行后续 | ||
0 | 1 | 1 | 2 | 1 | 2 | [1,2,3,4,4,5] |
1 | 2 | 2 | 3 | 2 | 3 | [1,2,3,4,4,5] |
2 | 3 | 3 | 4 | 3 | 4 | [1,2,3,4,4,5] |
3 | 4 | 4 | 4 | 不执行后续 | ||
3 | 5 | 4 | 5 | 4 | 4 | [1,2,3,4,5,5] |
如上,最终返回的是i+1,也就是标红色的4+1,数组里面1,2,3,4,5有五个不重复的数字,最后一个5就无需管它。i 这里就像是计数符 |
写法3
小伙伴可以去自行测试和第二个类似,但是写法2的时间和空间复杂度是最低的!!
var removeDuplicates = function (nums) {
let i = 0
for (let j = 0; j < nums.length; j++) {
if (i < 1 || nums[i - 1] != nums[j]) {
nums[i] = nums[j]
i++
}
}
return i
}
console.log(removeDuplicates([1, 3, 3, 4, 4, 5]))
参考了这篇文章,感谢他给了我思路,让我能够看懂。力扣:删除排序数组中的重复项js版 - 掘金
结尾:
学习id: 201903090124-48
现在是大三学生,学习到了vue阶段,如有不对的地方,欢迎指正,一起努力呀。如有转载请注明出处
如果要转载,请通知俺,并声明出处。