【问题标题】:Remove Duplicates from Sorted Array JS从排序数组 JS 中删除重复项
【发布时间】:2021-01-27 04:33:45
【问题描述】:

我试图了解为什么我对这个问题的解决方案只是部分有效。

问题:

给定一个排序数组 nums,就地删除重复项,使每个元素只出现一次并返回新长度。

不要为另一个数组分配额外的空间,您必须通过使用 O(1) 额外内存就地修改输入数组来做到这一点。

我的解决方案:

var removeDuplicates = function(nums) {
    
    if (nums.length === 0) return 0;
    for (let i = 1; i <= nums.length; i++){
        if(nums[i] === nums[i-1]){
            nums.splice(nums[i], 1);
        }
    }
    return nums.length;
};

这是我在 leetcode 上得到的结果,但我不明白为什么我的解决方案停止工作并且“3s”没有被删除?

输出截图:

【问题讨论】:

  • 您迭代 forward 并删除项目。每次移除时,该项目之后 的所有内容都会移回一个插槽。所以,如果你得到一个像 [15, 19, 19, 19, 21] 这样的数组,你会发现索引 1 和 2 相同,删除一个,那么索引 2 中的 new 项就是旧索引 3 中的 19。但是,您只需增加计数器 i 而从不检查它,而是检查(新)索引 2 和 3。

标签: javascript arrays


【解决方案1】:

C#简单解决方案:

public int RemoveDuplicates(int[] nums) {
        if (nums.Length == 0)
                return 0;
        var i = 0;
            var start = 0;
            var end = 0;

            while (end < nums.Length)
            {
                if (nums[start] != nums[end])
                {
                    nums[++i] = nums[end];
                    start = end;
                }
                end++;
            }

            return i + 1;
    }

【讨论】:

    【解决方案2】:
    function removeDuplicates(nums) {
      let i = 0;
      while(i < nums.length - 1) {
        i += 1 - ((nums[i] === nums[i+1]) && nums.splice(i, 1).length)
      }
      return nums.length;
    }
    

    【讨论】:

      【解决方案3】:

      这在常量内存上也可以很好地传递:

      const removeDuplicates = function (nums) {
          
          let count = 0;
          
          nums.forEach(function (num) {
              if (num !== nums[count]) {
                  nums[++count] = num;
              }
          });
          
          return nums.length && count + 1;
      };
      

      【讨论】:

      • 您的解决方案不会删除原始数组中的重复元素
      【解决方案4】:

      简单版。使用已经创建的函数

      let array = new Set(nums);
      let values = array.values();
      return Array.from(values);
      

      【讨论】:

      • 这使用了O(n)额外的内存,这是被禁止的
      • 不知道
      【解决方案5】:

      当您在迭代数组时拼接数组时,整个数组将就地更改。例如,假设索引 0 和 1 是重复的(i 是 1)。然后,如果您从数组中删除索引 1,则以前在索引 2 处的内容现在将在索引 1 处,以前在索引 3 处的内容现在将在索引 2 处,依此类推。

      所以,当一个元素被移除时,你需要将i减1,否则会跳过下一个元素。

      您还有一个逐个错误 - 将 i 从 1 迭代到 i &lt; nums.length,这样您就不会越过数组的末尾。

      您还需要将要删除的 index 传递给 splice,而不是要删除的 值。

      var removeDuplicates = function(nums) {
          for (let i = 1; i < nums.length; i++){
              if(nums[i] === nums[i-1]){
                  nums.splice(i, 1);
                  i--;
              }
          }
          return nums.length;
      };
      console.log(removeDuplicates([0, 0, 0]));

      【讨论】:

      • 另一种方法是从nums.length - 1 向后迭代到0。那么就不用担心维护索引了,元素的变化不会影响后面的迭代。
      猜你喜欢
      • 2016-10-01
      • 2021-11-12
      • 2016-01-24
      • 2022-01-03
      • 2021-12-12
      • 1970-01-01
      • 2013-11-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多