Move zeroes

Push every zero to the end in place, in one pass, without disturbing the order of the other values.

Time O(n)Space O(1)Code C#
Watch it animatedStep through it, with the running line highlighted. Free with an account.

The idea

write marks the end of the non-zero region built so far. Scan with read: whenever a non-zero value turns up, swap it down into the write slot and advance write. The zeros left behind by the swaps end up pushed to the back automatically.

Code

public static void MoveZeroes(int[] a) {
    int write = 0;
    for (int read = 0; read < a.Length; read++) {
        if (a[read] != 0) {
            (a[write], a[read]) = (a[read], a[write]);
            write++;
        }
    }
}

Tips

In the .NET library

A version that overwrites instead of swapping (copy a[read] to a[write], then zero-fill the tail) does one fewer comparison per step but needs a second pass to fill the zeros.