leetcode每天一题:【删除有序数组中的重复项】(简单)

108 阅读2分钟

这是我参与2022首次更文挑战的第18天,活动详情查看:2022首次更文挑战

题目描述

leetcode地址

提供一个有序的整数数组,请你直接在数组中删除重复出现的数字,最终实现每个数字只出现一次,然后返回数组的新长度。

举个例子:

数组:[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
};

image.png

第二种方法

第一种方法是可以解决问题,但是耗时有点长,下面咱们来看看第二种方法。

这个是利用双索引实现的,只使用了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
};

image.png

两种方法,第一种方法比较容易想到,但是时间复杂度高。

推荐第二种方法。