Field manual
Two pointers (same direction)
O(n)A slow write pointer and a fast read pointer both move left to right; the fast pointer scans ahead and the slow pointer only advances when a value is worth keeping.
Signals
remove duplicates in place, keep ordermove/partition elements while preserving ordercompact an array and use O(1) extra spaceshift zeros or a target value to the end
Template
function compact(arr) {
let slow = 0;
for (let fast = 0; fast < arr.length; fast++) {
if (shouldKeep(arr[fast], arr[slow])) {
arr[slow] = arr[fast];
slow++;
}
}
return slow; // new length
}Looks similar, isn't
- In-place array transform: In-place is the broader goal (rewrite one buffer, O(1) space); a slow/fast pair is the specific mechanic for it. Some in-place jobs, like reversing a fixed block, need no slow/fast pair at all.
- Two pointers (opposite ends): Opposite-end pointers start at both ends of sorted data and converge toward each other. Same-direction pointers both start at index 0 and only ever move forward, one reading and one writing.
n up to 1e5..1e6 -> O(n): the fast pointer visits each element once, the slow pointer never overtakes it, so one linear pass is enough.
Learn this pattern