【数据结构和算法 初级1】删除有序数组的重复项 暴力解法&双指针

题目描述【来自-右侧点击力扣】:

给你一个有序数组 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写法,如下表格

ii+1nums[i]nums[i+1]nums原数组 splice以后
0112
1223
2333[1,2,3,3,4,4,4,5,5,5]
注意,上面一行执行,数组少了一个元素,索引对应的值会变化。
3434这里不会发生变化,跳过了第二个重复的3,问题出在这里

而用while

ii+1nums[i]nums[i+1]nums原数组 splice以后
0112
1223
2333[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

jnums[i]nums[j]i++后的 ii++后的 nums[i]nums 替换后的数组
0011不执行后续
011212[1,2,3,4,4,5]
122323[1,2,3,4,4,5]
233434[1,2,3,4,4,5]
3444不执行后续
354544[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阶段,如有不对的地方,欢迎指正,一起努力呀。如有转载请注明出处

如果要转载,请通知俺,并声明出处。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值