githubEdit

01. Move All Zeroes to End

βœ… GFG solution to Move All Zeroes to End: rearrange array by moving zeros to end while maintaining order using efficient two-pointer technique. πŸš€

The problem can be found at the following link: πŸ”— Question Linkarrow-up-right

🧩 Problem Description

You are given an array arr[] of non-negative integers. You have to move all the zeros in the array to the right end while maintaining the relative order of the non-zero elements. The operation must be performed in place, meaning you should not use extra space for another array.

πŸ“˜ Examples

Example 1

Input: arr[] = [1, 2, 0, 4, 3, 0, 5, 0]
Output: [1, 2, 4, 3, 5, 0, 0, 0]
Explanation: There are three 0s that are moved to the end while maintaining 
the relative order of non-zero elements.

Example 2

Input: arr[] = [10, 20, 30]
Output: [10, 20, 30]
Explanation: No change in array as there are no 0s.

Example 3

πŸ”’ Constraints

  • $1 \le \text{arr.size()} \le 10^5$

  • $0 \le \text{arr}[i] \le 10^5$

βœ… My Approach

The optimal solution uses Two-Pointer In-Place Rearrangement:

Two-Pointer Strategy

  1. Key Insight:

    • Use a pointer to track the position where the next non-zero element should be placed.

    • Traverse the array and move non-zero elements to their correct positions.

    • This automatically pushes zeros to the end.

  2. Position Tracking:

    • Maintain a pos pointer starting at index 0.

    • This pointer always points to the next position for a non-zero element.

    • When we find a non-zero element, place it at pos and increment pos.

  3. In-Place Operation:

    • Simply copy non-zero elements to positions 0, 1, 2, ...

    • After all non-zeros are placed, fill remaining positions with zeros.

    • This maintains relative order and works in-place.

  4. Algorithm Steps:

    • Iterate through array with index i.

    • If arr[i] != 0, copy it to arr[pos] and increment pos.

    • After loop, fill arr[pos] to arr[n-1] with zeros.

    • Return the modified array.

Why This Works: By copying non-zeros to the front sequentially, we preserve their order. Filling remaining positions with zeros pushes all zeros to the end.

πŸ“ Time and Auxiliary Space Complexity

  • Expected Time Complexity: O(n), where n is the size of the array. We make a single pass to move non-zero elements, and another pass to fill zeros in the remaining positions, resulting in linear time.

  • Expected Auxiliary Space Complexity: O(1), as we perform the rearrangement in-place using only a constant amount of extra space for pointer variables.

πŸ§‘β€πŸ’» Code (C++)

chevron-right⚑ View Alternative Approaches with Code and Analysishashtag

πŸ“Š 2️⃣ Swap-Based Two-Pointer

πŸ’‘ Algorithm Steps:

  1. Use a pointer to track position for next non-zero element.

  2. When non-zero element found, swap with element at tracked position.

  3. Increment position pointer after each swap.

  4. This preserves order and moves zeros to end in single pass.

πŸ“ Complexity Analysis:

  • Time: ⏱️ O(n) - Single pass with swaps

  • Auxiliary Space: πŸ’Ύ O(1) - In-place with constant space

βœ… Why This Approach?

  • Single pass solution

  • Uses swap instead of copy + fill

  • Elegant and widely used approach

πŸ“Š 3️⃣ Stable Partition Approach

πŸ’‘ Algorithm Steps:

  1. Use stable partition to separate non-zeros and zeros.

  2. Maintain relative order during partitioning.

  3. All non-zeros move to front, zeros to end.

  4. STL stable_partition maintains element order.

πŸ“ Complexity Analysis:

  • Time: ⏱️ O(n) - Linear partitioning

  • Auxiliary Space: πŸ’Ύ O(1) - In-place partition

βœ… Why This Approach?

  • One-liner solution using STL

  • Clean and concise

  • Maintains stability automatically

πŸ“Š 4️⃣ Count and Fill Approach

πŸ’‘ Algorithm Steps:

  1. Count number of non-zero elements.

  2. Create temporary storage for non-zeros.

  3. Fill original array with non-zeros first, then zeros.

  4. Two-pass solution with explicit separation.

πŸ“ Complexity Analysis:

  • Time: ⏱️ O(n) - Linear time with multiple passes

  • Auxiliary Space: πŸ’Ύ O(n) - Temporary array for non-zeros

βœ… Why This Approach?

  • Very clear and easy to understand

  • Good for educational purposes

  • Explicit separation of concerns

πŸ†š πŸ” Comparison of Approaches

πŸš€ Approach

⏱️ Time Complexity

πŸ’Ύ Space Complexity

βœ… Pros

⚠️ Cons

🎯 Copy + Fill

🟒 O(n)

🟒 O(1)

πŸš€ Simple two-pass solution

πŸ”§ Two passes required

πŸ”„ Swap-Based

🟒 O(n)

🟒 O(1)

⚑ Single pass with swaps

πŸ”§ Swap overhead

πŸ“Š Stable Partition

🟒 O(n)

🟒 O(1)

🎯 One-liner, clean

πŸ”§ STL dependency

πŸ“ˆ Count and Fill

🟒 O(n)

πŸ”΄ O(n)

πŸ“– Very clear logic

πŸ’Ύ Extra space required

πŸ† Best Choice Recommendation

🎯 Scenario

πŸŽ–οΈ Recommended Approach

πŸ”₯ Performance Rating

πŸ… Optimal performance needed

πŸ₯‡ Swap-Based

β˜…β˜…β˜…β˜…β˜…

πŸ“– Readability priority

πŸ₯ˆ Copy + Fill

β˜…β˜…β˜…β˜…β˜…

πŸ”§ Shortest code

πŸ₯‰ Stable Partition

β˜…β˜…β˜…β˜…β˜†

🎯 Learning purposes

πŸ… Count and Fill

β˜…β˜…β˜…β˜…β˜†

β˜• Code (Java)

🐍 Code (Python)

🧠 Contribution and Support

For discussions, questions, or doubts related to this solution, feel free to connect on LinkedIn: πŸ“¬ Any Questions?arrow-up-right. Let's make this learning journey more collaborative!

⭐ If you find this helpful, please give this repository a star! ⭐


πŸ“Visitor Count

Visitor counter

Last updated