In-place Algorithm to Move Zeros to End of List in JavaScript

Moving zeros to the end of an array while maintaining the order of non-zero elements is a common programming problem in JavaScript. This article explores two efficient approaches to solve this problem: the in-place two-pointer method and the count-and-fill approach.

Problem Statement

Given an array containing integers including zeros, we need to move all zeros to the end while preserving the relative order of non-zero elements. The goal is to achieve this efficiently, ideally in a single pass through the array.

For example, given the input array:

[2, 5, 0, 1, 0, 8, 0, 3]

The desired output should be:

[2, 5, 1, 8, 3, 0, 0, 0]

Notice how all non-zero elements maintain their original relative positions, while all zeros are moved to the end.

Method 1: Two-Pointer Approach (In-Place)

The two-pointer technique uses two pointers to efficiently rearrange elements in-place. One pointer (i) traverses the entire array, while another pointer (j) tracks the position where the next non-zero element should be placed.

How It Works

Initialize both pointers at the start of the array. As we iterate with pointer i, whenever we find a non-zero element, we swap it with the element at position j and increment j. This ensures all non-zero elements are moved to the left side of the array.

function moveZerosToEnd(nums) {
   let i = 0;
   let j = 0;
   const len = nums.length;
 
   while (i < len) {
      if (nums[i] !== 0) {
         [nums[i], nums[j]] = [nums[j], nums[i]];
         j++;
      }
      i++;
   }
 
   return nums;
}
 
// Example usage:
const nums = [0, 1, 0, 3, 12];
console.log("Original array:", nums);
console.log("After moving zeros:", moveZerosToEnd([...nums]));
Original array: [ 0, 1, 0, 3, 12 ]
After moving zeros: [ 1, 3, 12, 0, 0 ]

Method 2: Count and Fill Approach

This approach first counts the number of zeros in the array, then creates a new array by adding non-zero elements first, followed by the counted number of zeros.

How It Works

Iterate through the array once to count zeros and collect non-zero elements. Then append the required number of zeros to complete the transformation.

function moveZerosToEnd(nums) {
   let count = 0;
   const result = [];
 
   for (let i = 0; i < nums.length; i++) {
      if (nums[i] === 0) {
         count++;
      } else {
         result.push(nums[i]);
      }
   }
 
   while (count > 0) {
      result.push(0);
      count--;
   }
 
   return result;
}
 
// Example usage:
const nums2 = [0, 1, 0, 3, 12];
console.log("Original array:", nums2);
console.log("After moving zeros:", moveZerosToEnd(nums2));
Original array: [ 0, 1, 0, 3, 12 ]
After moving zeros: [ 1, 3, 12, 0, 0 ]

Comparison

Method Space Complexity Time Complexity In-Place?
Two-Pointer O(1) O(n) Yes
Count and Fill O(n) O(n) No

Key Points

  • The two-pointer approach is more memory-efficient as it modifies the array in-place
  • Both methods preserve the relative order of non-zero elements
  • The count-and-fill approach is easier to understand but uses additional memory
  • Both algorithms have O(n) time complexity with a single pass through the array

Conclusion

The two-pointer approach is generally preferred for moving zeros to the end due to its O(1) space complexity and in-place modification. Choose the count-and-fill method when you need to preserve the original array or when readability is more important than memory efficiency.

Updated on: 2026-03-15T23:19:00+05:30

1K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements