What it is
"In-place" is a constraint more than a single technique: the interviewer wants the transformation done by overwriting the given array, matrix, or tree using O(1) or O(log n) extra space, instead of building a second structure and copying back. The actual mechanics vary by problem — a read/write pointer pair that compacts an array, a index-as-marker trick that reuses array slots to record what's been seen, cycle-following swaps that place each element directly into its final position, or layer-by-layer swaps for a matrix — but all of them share the discipline of never overwriting a value before you've captured what you still need from it.
When it applies
- The array is already sorted or has a fixed value range, letting you use array indices themselves (or their sign) as a marker instead of an extra hash set.
- You need to compact, dedupe, or partition an array in one pass, keeping a slow "write" pointer behind a fast "read" pointer.
- A square matrix needs a geometric transform (rotate, transpose, mirror) that can be expressed as a fixed sequence of position swaps.
- When the values aren't bounded by the array's own length (arbitrary integers, not
1..n), the index-as-marker trick doesn't apply and you may genuinely need a hash set — say so rather than forcing an in-place trick where it doesn't fit.
Tells in the problem
- "Modify in place," "do not allocate another array/matrix," or "O(1) extra space" stated explicitly.
- Values guaranteed to fall in
[1, n]for an array of lengthn— the strongest signal for the index-as-marker technique. - "Rotate," "transpose," or "mirror" applied to a square grid.
- A function that returns nothing (or just a new length) and is described as mutating its input argument directly.
- Two-value or three-value arrays that need partitioning without a full sort (a hint toward tracking multiple pointers rather than swapping pairs blindly).
The classic mistake
Overwriting a cell before reading the value that was about to be moved out of it — the most common form is using a sentinel or "already cleared" marker (like writing 0 into a matrix cell to mark "clear this row/column later") that then gets misread on a later pass as if it were original data, cascading zeros where none belonged. The general fix is to separate the "which positions need to change" decision from the "apply the change" step: record markers somewhere that can't be confused with real data (a matrix's first row/column, the sign bit of an in-range value, a rotation done via reversal instead of shifting) and only then perform destructive writes, checking each cell's original state before you decide anything from it.
Questions to start with
- Move Zeroes — the simplest read/write pointer compaction, with no value-range trick needed.
- Remove Duplicates from Sorted Array — the same two-pointer shape, using sortedness instead of a target value to decide what to keep.
- Sort Colors — three-way partitioning with three pointers instead of two, in a single pass.
- Rotate Array — a rotation done through triple reversal, avoiding both extra space and a full explicit shift.
- Find All Duplicates in an Array — the index-as-marker trick: negate the value at an index to record "this value has been seen."
- Rotate Image — a matrix transform expressed as transpose-then-reverse instead of layer-by-layer swaps.
- Set Matrix Zeroes — the hardest of the set: markers must be stored without being confused with the data being cleared.