Read / Write Heads
Two pointers walk the same array in the same direction: a read head scans every element, and a write head marks where the next kept element belongs. Whatever the read head decides to keep gets written at the write head, which only then advances - so the prefix [0, write) is always the compacted answer.