最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Move zeroes to end of array in javascript - how to return nothing? - Stack Overflow

programmeradmin2浏览0评论

I am attempting to complete a leetcode question in JS. I am new to algorithms in general, and am having some trouble getting my first submission accepted.

The question specifies the following:

Given an array nums, write a function to move all 0's to the end of it while maintaining the relative order of the non-zero elements.

For example, given nums = [0, 1, 0, 3, 12], after calling your function, nums should be [1, 3, 12, 0, 0].

Note: You must do this in-place without making a copy of the array. Minimize the total number of operations.


With that, here is my code:

/**
 * @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;
};

The comments at the top of the code sample are provided in their text editor, and led me to believe that I am not supposed to provide any return statement. Though the validator on their site seemed to not want to accept that at all, so I started returning null...

When I log my nums to the console after handling the input, I am seeing the desired result nums = [1, 3, 12, 0, 0]. Regardless my answer keeps getting rejected. I would love to understand what I am doing wrong here, so I can fix it.

I understand this may be a duplicate. I saw other responses dealing with C and Java, but none I saw dealt with JS.

I am attempting to complete a leetcode.com question in JS. I am new to algorithms in general, and am having some trouble getting my first submission accepted.

The question specifies the following:

Given an array nums, write a function to move all 0's to the end of it while maintaining the relative order of the non-zero elements.

For example, given nums = [0, 1, 0, 3, 12], after calling your function, nums should be [1, 3, 12, 0, 0].

Note: You must do this in-place without making a copy of the array. Minimize the total number of operations.


With that, here is my code:

/**
 * @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;
};

The comments at the top of the code sample are provided in their text editor, and led me to believe that I am not supposed to provide any return statement. Though the validator on their site seemed to not want to accept that at all, so I started returning null...

When I log my nums to the console after handling the input, I am seeing the desired result nums = [1, 3, 12, 0, 0]. Regardless my answer keeps getting rejected. I would love to understand what I am doing wrong here, so I can fix it.

I understand this may be a duplicate. I saw other responses dealing with C and Java, but none I saw dealt with JS.

Share Improve this question edited Oct 26, 2015 at 12:28 Tomáš Zato 53.1k63 gold badges307 silver badges821 bronze badges asked Oct 26, 2015 at 12:14 robabbyrobabby 2,2006 gold badges32 silver badges47 bronze badges 7
  • Remove the return null altogether. – Griffith Commented Oct 26, 2015 at 12:19
  • 1) 'returning void', means : do not return anything. So just write 'return;' or do not write any return statement. 2) by using sort and the right sort function, you can write the answer in very little code. – GameAlchemist Commented Oct 26, 2015 at 12:20
  • Your loop should be going from the end to the beginning. – epascarello Commented Oct 26, 2015 at 12:24
  • The title of your question is misleading. I propose to change it to "How to let the return statement return nothing?" It would be better if you would not mention that the exercise is about sorting, so that readers can focus on the essence of your question. – www.admiraalit.nl Commented Oct 26, 2015 at 12:25
  • I was wondering if you could totally remove the temp completely, and push(0) instead. So the lines inside if would be nums.splice(i,1); nums.push(0). – Iggy Commented Nov 7, 2017 at 18:01
 |  Show 2 more comments

24 Answers 24

Reset to default 14

The problem has nothing to do with the return statement, the issue is your algorithm is wrong.

[0,0,1,2,3] will return [0,1,2,3,0]

When you loop in the positive direction and remove indexes, you skip indexes as the next index slides down to the position you already covered.

You need to loop in the negative direction. Start at the end and go to the start.

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

This is an O(n) solution to the problem:

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;
};

As everyone has already stated: when it says do not return anything, simply do not write a return statement.

However, there is a problem with your code. Use the test case [0,0,1]. If you start at the first element so it moves it to the back of the array, [0,1,0]. Now your loop index is looking at the second element which is 1. you've completely missed the second 0.

function myFunction(n) {
  // here i have created zeros array to store all zeros.
  let zeros = [];
  // here i filter out zeros first n array and push them at
  // same time to zeros array..
  n = n.filter(item => (item !== 0 ? true : zeros.push(item) && false))
  // finally i just max the zeros array at end of n array
  return n.concat(zeros)
}

If you must provide a return statement, but you are not allowed to return anything, you can just write

return;

Nothing in javascript

null is not nothing, technically. Try this: typeof null. You get "object", which is pretty much something. If you run a function that really doesn't return anything:

(function(){})();

You will see undefined in console. So either return undefined or just return or nothing at all will be considered OK.

Sorting alternative solution

I just want to propose more practical solution, to give you another point of view. Since it's javascript, you can use sort function. You will have to create your own callback to compare elements though:

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

Now in your specific case, what do we want? We state, that

a is smaller than b if and only if a is zero and b is not zero.

So our callback:

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

Used like this:

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;
    });

This is what we usually do when actually writing a program, because it's easier to understand (once you get used to it), and shorter most of the time.

Try this approach with ES6 Features

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

This approach can also be used. With two pointers

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);

You can iterate each slot, and fill it will a value that comes from another index, one that moves ahead faster when it skips zeroes. The ?? operator can be used when that second index gets out of range:

function moveZeroes(nums) {
    for (let i = 0, j = 0; i < nums.length; i++) {
        while (nums[j] === 0) j++; // skip zeroes
        nums[i] = nums[j++] ?? 0;
    }
}

  const moveZeros = (arr) => {
  const newArray = [];
  const allZeros = [];
  for(i=0; i < arr.length; i++){
      if(arr[i] >= 1){
        newArray.push(arr[i]);
    }else{
      allZeros.push(arr[i])
    }
  }
  return newArray.concat(allZeros);
}

const zeros = moveZeros([1, 3, 5, 0, 7, 0]);
console.log(zeros);

You can try this function:

const shiftIt = array => {
    let temp = [...array];
    let zeroCounter=0;
    for(let i=0;i<array.length;i++){
        if(array[i] === 0 ){
            array.push(array.splice(i, 1)[0]);
            i--
            zeroCounter ++
        }
        if(i+zeroCounter+1 === array.length) break;
    }
    return array
}

shiftIt([1,0,2,3,0,0,0,4]) // [1,2,3,4,0,0,0,0]

Every time an element of array equals to zero, I send it to the end of array. So all of the other elements shift to left and I have to make i-- . We get stuck at infinity when all zeros go to the right side of the array. We consider the sum of these two conditions as the condition to exit the loop, since we know how many zeros there are and also where we are now is the end point of the non-zero elements.

The shared approach is not suitable for two or more consecutive zeros, below is example:

nums = [0,0,1]

  • At index=0 output ==> [0,1,0]
  • At index=1 output ==> [0,1,0] Here we are checking index 1 which is nonzero but we miss the 0 at index 0 and result gets messed up.

Here is my approach to resolve the problem:

   var moveZeroes = function(nums) {
    let len = nums.length
    if(len<=1)return nums
   let zeroCount=0;
   for(let i=0;i<len;i++){
       if(nums[i]===0)zeroCount++
       else if(nums[i]!=0&&zeroCount!=0){
           nums[i-zeroCount]=nums[i]
           nums[i]= 0
       }
   } 
};

Sort the array by ascending order than loop from end to beginning to find zeros. When you find it, splice the array which will remove the current index and push zero

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);
    }
   }
};

// javascript // single array operation:

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));

// multiple array operation => another approach // algorithm: push all non zero elements in an array and all zeros in another array // concat them once loop terminates

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));

It can be done this way too :

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);
    }
};

Try this one

 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))

Here is the simple one

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;
    }

Splice() is used to remove the element (zero in this case). Then, push a zero to the end of the array.

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

Here is a very simple solution:

Time complexity 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))

I would give alternate solution. Remove the 0's then add them at the end. Time Complexity: O(n) Space Complexity: 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;
};

var x = [1,0,0,0,1,0,1];
for(i=x.length-1;i>=0;i--)
    x[i]!=0 && x.unshift(x.splice(i,1)[0])
console.log(x);

Try this:

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;
};

Moving Zeros to End of Array with 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("]");
        }
    }

}
发布评论

评论列表(0)

  1. 暂无评论