【问题标题】:Move zeroes to end of array in javascript - how to return nothing?在javascript中将零移动到数组的末尾-如何不返回任何内容?
【发布时间】:2015-10-26 12:14:48
【问题描述】:

我正在尝试在 JS 中完成 leetcode.com question。总的来说,我是算法新手,在第一次提交时遇到了一些麻烦。

问题指定以下内容:

给定一个数组nums,编写一个函数将所有的 0 移到它的末尾,同时保持非零元素的相对顺序。

例如,给定nums = [0, 1, 0, 3, 12],在调用你的函数后,nums 应该是[1, 3, 12, 0, 0]

注意: 您必须在不复制数组的情况下就地执行此操作。 尽量减少操作的总数。


这样,这是我的代码:

/**
 * @param {number[]} nums
 * @return {void} Do not return anything, modify nums in-place instead.
 */
var moveZeroes = function(nums) {
    var i, temp;

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

代码示例顶部的 cmets 是在其文本编辑器中提供的,这让我相信我不应该提供任何 return 语句。尽管他们网站上的验证器似乎根本不想接受,所以我开始返回 null...

当我在处理输入后将nums 记录到控制台时,我看到了所需的结果nums = [1, 3, 12, 0, 0]。不管我的回答一直被拒绝。我很想知道我在这里做错了什么,所以我可以解决它。

我知道这可能是重复的。我看到了其他关于 C 和 Java 的回复,但没有看到关于 JS 的回复。

【问题讨论】:

  • 完全删除return null
  • 1) 'returning void',意思是:不返回任何东西。所以只要写'return;'或者不写任何返回语句。 2)通过使用排序和正确的排序函数,你可以用很少的代码写出答案。
  • 你的循环应该是从头到尾的。
  • 您的问题的标题具有误导性。我建议将其更改为“如何让return语句不返回任何内容?”最好不要提到这个练习是关于排序的,这样读者就可以专注于你问题的本质。
  • 我想知道你是否可以完全删除临时文件,然后用 push(0) 代替。所以 if 里面的行是nums.splice(i,1); nums.push(0).

标签: javascript arrays algorithm


【解决方案1】:

问题与return语句无关,问题是你的算法错误。

[0,0,1,2,3] 将返回 [0,1,2,3,0]

当您在正方向循环并删除索引时,您会跳过索引,因为下一个索引会向下滑动到您已经覆盖的位置。

你需要在负方向循环。从尽头开始。

for (i = nums.length-1; i>=0; i--) {

【讨论】:

    【解决方案2】:

    这是该问题的 O(n) 解决方案:

    var moveZeroes = function (nums) {
      let count = 0;
      
      for (let i = 0; i < nums.length; i++) {
        if (nums[i] !== 0) {
          nums[count++] = nums[i];
        }
      }
    
      for (let i = count; i < nums.length; i++) {
        nums[i] = 0;
      }
      
      return nums;
    };
    

    【讨论】:

      【解决方案3】:

      正如大家已经说过的:当它说不返回任何东西时,就不要写返回语句。

      但是,您的代码有问题。使用测试用例 [0,0,1]。 如果您从第一个元素开始,则它将其移动到数组的后面,[0,1,0]。现在您的循环索引正在查看第二个元素 1。您完全错过了第二个 0。

      【讨论】:

        【解决方案4】:

        如果你必须提供return语句,但你不能返回任何东西,你可以写

        return;
        

        【讨论】:

          【解决方案5】:

          javascript 中没有任何内容

          null 在技术上不是什么都不是。试试这个:typeof null。你会得到"object",这很重要。如果你运行一个真正不返回任何东西的函数:

          (function(){})();
          

          您将在控制台中看到undefined。所以return undefined 或者只是return 或者什么都不会被认为是好的。

          排序替代解决方案

          我只是想提出更实际的解决方案,给你另一个观点。由于它是 javascript,因此您可以使用排序功能。不过,您必须创建自己的回调来比较元素:

          array.sort(function(a, b) { ... comparison here ... });
          

          现在,在您的具体情况下,我们想要什么?我们声明,

          a 小于 b 当且仅当 a 为零且b 零。

          所以我们的回调:

          function(a, b) {
              if(a==0 && b!=0)
                  return 1;
              else if(b==0 && a!=0)
                  return -1;
              else 
                  return 0;
          }
          

          这样使用:

          var array = [2,6,0,666,-6,142,0,1,-10];
          array.sort(function(a, b) {
                  if(a==0 && b!=0)
                      return 1;
                  else if(b==0 && a!=0)
                      return -1;
                  else 
                      return 0;
              });
          

          这是我们在实际编写程序时通常会做的事情,因为它更容易理解(一旦你习惯了它),而且大部分时间更短。

          【讨论】:

          • 数组项是数字。排序函数可以写成 function(a, b) { return (a*b ? 1 : ( b ? -1 : 0)); }
          • 是的,这是一个不错的捷径,干得好。但即使我想到了这一点,我也不会用它来回答,因为乍一看有点不清楚。
          • 排序是线性的,但我们可以在这里做线性。它还假设排序的稳定性。
          【解决方案6】:

          用 ES6 特性试试这个方法

          let filteredArr = nums.filter((elem) => {
              return elem !== 0;
          }) // Create a new Array with all non zero elements
          
          let countOfZero = nums.length - filteredArr.length // Get Count of Zero elements
          
          let newArr = [...filteredArr,...Array(countOfZero).fill(0)] // Create a new array containig only zero equivalent to count of zero elements and filtered non zero elements Array 
          
          return nums.splice(0,nums.length,...newArr) // Use splice to alter original array and then add new Array using spread operator
          

          【讨论】:

            【解决方案7】:

            也可以使用这种方法。有两个指针

            function shift(arr) {
              let i = 0;
              let j = arr.length - 1;
            
              while (j > i) {
                if (arr[i] === 0) {
                  // swapping the numbers --->
                  let last = arr[j];
                  arr[j] = arr[i];
                  arr[i] = last;
                  j--;
                } else {
                  i++;
                }
              }
            
              return;
            }
            
            let arr = [1, 2, 0, 7, 9, 0, 3, 0]
            shift(arr)
            console.log(arr);

            【讨论】:

              【解决方案8】:

              按升序对数组进行排序,而不是从头到尾循环查找零。 当你找到它时,拼接将删除当前索引并推零的数组

              var moveZeroes = function(nums) {
                nums.sort((a,b) => {return a-b});
                 for(let index = nums.length - 1; index >= 0 ; index--){
                  if(nums[index] === 0){
                    nums.splice(index, 1);
                    nums.push(0);
                  }
                 }
              };
              

              【讨论】:

              • .splice 是线性的,因此您的整体算法是二次的。还 .sort() 杀死原始订单。
              【解决方案9】:

              // javascript // 单个数组操作:

              var a = [1, 2, 0, 0, 3, 0, 3, 0, 2, 0, 0, 0, 5, 0];
              function moveZero(b) {
                  for (var i = b.length - 1; i >= 0; i--) {
                      if (b[i] === 0) {
                          b.splice(i, 1);
                          b.push(0);
                      }
                  }
                  return b;
              }
              console.log(moveZero(a));
              

              // 多数组操作 => 另一种方法 // 算法:推入一个数组中的所有非零元素和另一个数组中的所有零 // 一旦循环终止就连接它们

              var a = [1, 2, 0, 0, 3, 0, 3, 0, 2, 0, 0, 0, 5, 0];
              var b = [];
              var c = [];
              
              function moveZero(data) {
              
                  for (var i = 0; i < data.length - 1; i++) {
                      if (data[i] !== 0) {
                          b.push(data[i]);
                      } else {
                          c.push(0)
                      }
                  }
                  if (c.length > 0) {
                      b = b.concat(c);
                  }
                  return b;
              }
              console.log(moveZero(a));
              

              【讨论】:

                【解决方案10】:

                也可以这样做:

                var moveZeroes = function(nums) {
                    var len = nums.length, i = nums.indexOf(0);
                    while(~i && i < --len){
                        nums.splice(i, 1);
                        nums.push(0);
                        i = nums.indexOf(0);
                    }
                };
                

                【讨论】:

                  【解决方案11】:

                  试试这个

                   function order(array){
                    count = 0;
                    for(var i=0;i<array.length;i++){
                      if(array[i] !== 0){
                        //non zero element count
                        array[count] = array[i]
                  
                        count++;
                  
                  
                      }
                    }
                  
                    while(count<array.length){
                  
                      array[count] = 0
                  
                      count++
                    }
                  
                    return array
                  }
                  var array = [1, 9, 8, 4, 0, 0, 2, 7, 0, 6, 0]
                  console.log(order(array))
                  

                  【讨论】:

                  • 我们为什么要试试这个?是什么使它比现有答案更好?这似乎是this existing answer 的重复。感谢您的澄清。
                  【解决方案12】:

                  这是一个简单的

                  function check(arr){
                        var i=0;
                        var j=arr.length-1;
                        while(j>i+1){
                          if(arr[i]!==0){
                            i++;
                          }
                          if(arr[j]===0){
                            j--;
                          }
                          if(arr[i]===0){
                            arr[i]=arr[j];
                            arr[j]=0;
                          }
                        }
                       return arr;
                      }

                  【讨论】:

                    【解决方案13】:

                    Splice() 用于删除元素(在这种情况下为零)。然后,将零压入数组末尾。

                     var moveZeroes = function (nums) {
                      var length = nums.length;
                      while (length-- > -1) {
                        if (nums[length] == 0) nums.splice(length, 1).push(0);
                      }
                      return nums;
                    };
                    

                    【讨论】:

                    • 这会从数组中删除零。
                    • .push(0); 在这里什么都不做,因为它在一个临时数组上运行,该数组直接进入垃圾收集器并且从未被分配。我不明白代码的意义。
                    【解决方案14】:
                    function pushZerosToEnd(arr) {
                    
                                var k=0;
                    
                                for(let i=0; i<arr.length; i++)
                                {
                                    if(arr[i] !==0)
                                    {
                                        let temp=arr[i];
                                        arr[i]=arr[k];
                                        arr[k]=temp;
                                        k++;
                                    }
                                }
                                return arr;
                        }
                      console.log(pushZerosToEnd([0, 1, 2, 0, 3, 0, 5, 6]));
                    

                    【讨论】:

                    • 编辑你的答案缩进并添加一个简短的解释。
                    【解决方案15】:

                    这是一个非常简单的解决方案:

                    时间复杂度 O(n)

                    var moveZeroes = function(nums) {
                        var i = nums.length;
                        while (i > -1) {
                            let current = nums[i];
                            if(nums[i] === 0) {
                                nums.splice(i,1)
                                nums.push(current)
                            } 
                           i--; 
                        }
                        return nums;
                    };
                    let arr = [0,1,0,3,12]
                    console.log(moveZeroes(arr))

                    【讨论】:

                    • splice 的时间复杂度是线性的,因为它将所有元素向前移动,所以整体时间复杂度是 O(n^2),而不是 O(n)。
                    【解决方案16】:

                    我会提供替代解决方案。 删除 0,然后在末尾添加它们。 时间复杂度:O(n) 空间复杂度:O(1)

                    var moveZeroes = function(nums) {
                        let countZeros = 0;
                        for (let i = 0; i < nums.length;) 
                        {
                            if(nums[i] === 0) //remove zeros and increment the counter
                            {
                                nums.splice(i, 1);
                                countZeros++;
                            } 
                            else // to deal with input which starts with 0 
                            {
                              i++;
                            }      
                        }
                        for (let j = 0; j < countZeros; j++) //add zeros at the end
                        {
                            nums.push(0); 
                        }
                        return nums;
                    };

                    【讨论】:

                    • 时间复杂度是二次的,不是线性的。 splice 要求 i 之后的所有元素都向前移动以填补该空白。这是一个线性运算,所以嵌套在一个循环中给出 O(n^2)。
                    【解决方案17】:

                    使用 JAVA 将零点移至数组末尾

                    import java.util.Arrays;
                    
                    public class MoveZerosToEndWithJava {
                    
                        public static void main(String[] args) {
                            // TODO Auto-generated method stub
                            int[] A = { 6, 8, 0, 2, 3, 0, 4, 1 };
                    
                            moving(A);
                        }
                    
                        public static void moving(int[] a) {
                    
                            int countZero = 0;
                            System.out.println(Arrays.toString(a));
                            System.out.print("[");
                            for (int i = 0; i < a.length; i++) {
                                if (a[i] == 0) {
                                    countZero++;
                                } else {
                                    if (i + 1 == a.length && countZero == 0) {
                                        System.out.print(a[i] + "]");
                                    } else {
                                        System.out.print(a[i] + ", ");
                                    }
                                }
                            }
                            for (int i = 0; i < countZero; i++) {
                                if (i + 1 == countZero) {
                                    System.out.print("0");
                                } else
                                    System.out.print("0, ");
                            }
                            if (countZero > 0) {
                                System.out.println("]");
                            }
                        }
                    
                    }
                    

                    【讨论】:

                    • 这是一个 JavaScript 问题,不是 Java。
                    • 第一行说使用 JAVA 将零点移动到数组末尾。顺便谢谢
                    • 好吗?你这么说的事实并没有使它与关于 JavaScript 的问题无关。
                    • 这是为所有想使用 Java 的人准备的。
                    • 这是一个关于如何在 JavaScript 中做到这一点的问题。看到这个问题的人会想知道如何在 JavaScript 中做到这一点。如果他们想知道如何在 Java 中做到这一点,他们会寻找有关 Java 的问题。
                    【解决方案18】:

                    试试这个:

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

                    【讨论】:

                    • 他们为什么要试试这个?请解释它是如何工作的以及为什么你认为它是最好的解决方案。不幸的是,splice 是线性的,所以你有一个不必要的二次解。
                    猜你喜欢
                    • 2021-03-22
                    • 1970-01-01
                    • 2016-10-10
                    • 1970-01-01
                    • 1970-01-01
                    • 2019-07-19
                    • 2020-02-18
                    • 2021-10-01
                    相关资源
                    最近更新 更多