【问题标题】:Remove duplicates from sorted array and return length - Must mutate the original array从排序数组中删除重复项并返回长度 - 必须改变原始数组
【发布时间】:2020-07-07 15:02:45
【问题描述】:

免责声明

我很清楚重复的问题,但是这个问题要求在不创建新数组的情况下删除重复项,并希望我们改变原始数组。

说明

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

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

示例

给定nums = [1,1,2]

您的函数应返回长度 = 2,nums 的前两个元素分别为 1 和 2。

您在返回的长度之外留下什么并不重要。

尝试

const removeDuplicates = function(nums) {

   for(let i of nums){
     if(nums[i] === nums[i]){
        nums.splice(i, 1)
     }
   }
   return nums.length;
};

console.log(removeDuplicates([1, 1, 2]));
console.log(removeDuplicates([1, 2]));

// [1, 1, 2] => [1, 2] (Correct)
// [1, 2]    => [1]    (Incorrect - should be [1, 2])

我是否使用 splice 正确地改变了数组,我需要做什么来更正第二个参数?

另外,在 leetcode 中,当我运行第一个参数时,它说它是正确的并返回剩余元素的数组,但指令要求新数组的长度。不确定我是否遗漏了什么,但为什么它没有返回长度?

https://imgur.com/5cuhFYf

【问题讨论】:

  • splice 应该采用您要删除的值的索引,而不是值本身。尝试将您的数组更改为[3, 3, 2],看看会发生什么。
  • @HereticMonkey 给我2
  • if(nums[i] === nums[i]) 始终为真。
  • @Kosh 所以把它改成nums[i + 1]?
  • 是的。更改为i+1

标签: javascript arrays duplicates


【解决方案1】:

你在这里:

const removeDuplicates = function(nums) {

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

console.log(removeDuplicates([1, 1, 2]));
console.log(removeDuplicates([1, 2]));

【讨论】:

  • ++i 是什么意思?
  • @and1,增量
  • 这个++ii++有什么区别?
  • @and1, ++i 增加 i 比使用它,i++ 先使用 i 然后增加它。
  • @and1 递增“然后”使用
【解决方案2】:

let nums = [1,1,2];
nums = [...new Set(nums)].length;
console.log(nums);
nums = [1,1,2];
nums = nums.filter(function(item, pos, self) {
  return self.indexOf(item) == pos;
})
console.log(nums)

【讨论】:

  • 欣赏它,但这不是在改变原始数组吗?
  • 你可以这样写nums = [...new Set(nums)].length;
  • 他们说Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory.
【解决方案3】:

对于数组的每个元素,您需要遍历该数组的所有剩余元素,以检查所有重复项。不确定这是否比制作副本更高效。

const removeDuplicates = function (nums) {
    let i = 0;
    while (i < nums.length) {
        let j = i + 1;
        while (j < nums.length) {
            if (nums[i] === nums[j]) {
                nums.splice(j, 1);
            }
            else {
                j++;
            }
        }
        i++;
    }
    return nums.length;
};
console.log(removeDuplicates([1, 1, 2]));
console.log(removeDuplicates([1, 2]));
console.log(removeDuplicates([1, 2, 1, 3, 4, 3, 2, 1]));

// [1, 1, 2] => [1, 2] (Correct)
// [1, 2]    => [1]    (Incorrect - should be [1, 2])
// [1, 2, 1, 3, 4, 3, 2, 1] => [1, 2, 3, 4]

【讨论】:

    【解决方案4】:

    提示在行中:It doesn't matter what you leave beyond the returned length.

    问你这个问题的人希望你在数组中移动,跟踪 2 个指针:1) 输出数组的结尾和 2) 输入数组中的当前索引。

    如果你这样做,并且只在它们不同时将输入复制到输出指针,你最终会得到正确的输出、正确的长度(来自输出指针)和最后的一点垃圾数组。

    const unique = (arr) => {
      let output = 0;
      for (let input = 0; input < arr.length; input++) {
        if (arr[output] !== arr[input]) {
          output++;
          arr[output] = arr[input];
        }
      }
      return output + 1;
    }
    
    const arr = [1, 1, 2, 3, 3, 3, 4, 5, 5, 6, 8, 8, 8, 9, 11];
    const length = unique(arr);
    console.log(arr, length);
    

    【讨论】:

      【解决方案5】:

      我相信这个解决方案会通过更多的测试用例(至少在我的个人测试中)

        const removeDups = (nums) => {
        
        // since mutating arrays I like to start at the end of the array so when the index is removed it doesn't impact the loop
        let i = nums.length - 1;
      
        while(i > 0){
          // --i decrements then evaluates (i.e 5 === 4), i-- decriments after the evaluation (i.e 5 === 5 then decrements the last 5 to 4)
          if(nums[i] === nums[--i]){  
            // remove the current index (i=current index, 1=number of indexes to remove including itself)
            nums.splice(i,1);  
          }
        }
      
        console.log(nums);
        return nums.length;
      
      };
      
      // Test Cases 
      console.log(removeDups([1,1,2]));   // 2
      console.log(removeDups([0,0,1,1,1,2,2,3,3,4])); // 5
      console.log(removeDups([0,0,0,2,3,3,4,4,5,5])); // 5
      

      【讨论】:

        【解决方案6】:

        尝试了上面 Kosh 提供的解决方案,但是对于更大的数组 [0,0,1, 1, 1, 2, 2, 3, 3, 4] 失败了。所以最后写了我自己的。似乎适用于所有测试。

        var removeDuplicates = function(nums) {
          var i;
          for (i = 0; i <= nums.length; i++) {
            const tempNum = nums[i];
            var j;
            var tempIndex = [];
            for (j = i+1; j <= nums.length; j++) {
              if (tempNum === nums[j]) {
                tempIndex.push(j)
              }
            }
            nums.splice(tempIndex[0], tempIndex.length)
          }
          return (nums.length);
        };
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-04-27
          • 1970-01-01
          • 2016-10-01
          • 2021-11-12
          • 2021-01-27
          • 2018-07-10
          • 2013-09-26
          • 2016-01-24
          相关资源
          最近更新 更多