Skip to main content

Move zeros to End

 Index

Problem is we need to move all the zeros to the right and non-zeros to the left.

Move Zeros to End

Approaches we can follow are:

1st Approch : 

1. Your approach of swapping each 0 element with the end (j pointer) could work, but it requires some adjustments to handle the indices correctly. However, it’s less efficient than moving the non-zero elements to the front as it repeatedly swaps each 0 with elements toward the end, making it potentially 

O(n2)O(n^2) in the worst case due to unnecessary swaps.

Here's a refined version of your approach to help clarify the issues and make it function correctly:

Adjusted Code Using End-Pointer Swapping

  1. Initialize j to nums.size() - 1 (the last index).
  2. Traverse from the beginning, and for each 0, swap it with nums[j], then decrement j.

However, keep in mind that this will cause the relative order of non-zero elements to change.


class Solution {

public:

    void moveZeroes(vector<int>& nums) {

        int j = nums.size() - 1;  // Set j to the last index


        for (int i = 0; i <= j; i++) {

            if (nums[i] == 0) {

                // Swap zero element with nums[j]

                while (j > i && nums[j] == 0) {

                    j--;  // Decrement j to skip over trailing zeros

                }

                if (i < j) {  // Ensure i and j do not overlap

                    std::swap(nums[i], nums[j]);

                    j--;  // Move j backward after a successful swap

                }

            }

        }

    }

};

2nd Approach :

Your code has some issues and won't work as intended due to incorrect indexing. Here’s a breakdown:

1. The variable `j` is initially set to `nums.size()`, which is out of bounds (since array indices start from 0). It will cause out-of-bounds access.
2. Swapping with the end doesn't efficiently move all zeroes to the end in one traversal.
3. You need to track the position of the next non-zero element instead of swapping each zero with the end directly.

Here's an optimized approach:

- Use two pointers: one to iterate through the array (`i`) and another (`j`) to keep track of the position to place the next non-zero element.
- When you find a non-zero element, swap it with the element at `j` and increment `j`.

Here's the corrected code:

```cpp
class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        int j = 0;  // Pointer for the position of the next non-zero element

        // Move all non-zero elements to the front
        for (int i = 0; i < nums.size(); i++) {
            if (nums[i] != 0) {
                nums[j] = nums[i];
                j++;
            }
        }

        // Fill the rest with zeros
        for (; j < nums.size(); j++) {
            nums[j] = 0;
        }
    }
};
```

### Explanation
1. First loop: Places all non-zero elements at the beginning of `nums`.
2. Second loop: Fills the remaining elements with zeros.

This solution has \( O(n) \) time complexity and \( O(1) \) additional space complexity since it modifies the array in place.

Comments