Pattern Reference
Array Tricks
"Cyclic rotation, reversal-based operations, in-place swaps, and the Dutch flag."
Loading...
Deep Dive Tutorial
Array in-place manipulation problems have a deceptive pattern: the O(n) extra space solution is obvious, but the O(1) space version requires a non-trivial trick. Learn the three canonical tricks — 3-reversal rotation, negation marking, and index encoding — and you'll be able to solve a whole class of problems that seem impossible at O(1) space.
The Three Canonical Tricks
Rotate array, mark visited, index encoding
// TRICK 1: ROTATE ARRAY k positions (right) using 3 reverses
function rotate(nums, k) {
k = k % nums.length;
const rev = (lo, hi) => { while(lo<hi) [nums[lo++],nums[hi--]]=[nums[hi],nums[lo-1]]; };
rev(0, nums.length-1); // reverse all
rev(0, k-1); // reverse first k
rev(k, nums.length-1); // reverse remaining
}
// Why it works: [1,2,3,4,5], k=2
// reverse all: [5,4,3,2,1]
// reverse 0..k-1: [4,5,3,2,1]
// reverse k..n-1: [4,5,1,2,3] ✓
// TRICK 2: MARK VISITED by negating (array values 1..n)
// Visit index i → nums[nums[i]-1] = -|nums[nums[i]-1]|
// Check if value v is visited: nums[v-1] < 0
function findDuplicates(nums) {
const result = [];
for (const n of nums) {
const idx = Math.abs(n) - 1;
if (nums[idx] < 0) result.push(Math.abs(n)); // visited twice = duplicate
else nums[idx] = -nums[idx]; // mark visited
}
return result;
}
// TRICK 3: CYCLIC SORT (array with values 1..n)
// Place each number at index (value-1) by swapping
function cyclicSort(nums) {
let i = 0;
while (i < nums.length) {
const j = nums[i] - 1; // correct index for nums[i]
if (nums[i] !== nums[j]) [nums[i], nums[j]] = [nums[j], nums[i]]; // swap to correct pos
else i++; // already in place, move on
}
}
// After cyclic sort: nums[i] = i+1 iff no duplicate/missingWorked Problems
wrench
Array manipulation trick selector:
- "Rotate k positions in O(1) space" → 3 reverses
- "Mark visited without extra space (values 1..n)" → negate at index value-1
- "Place each value at correct index (1..n)" → cyclic sort
- "Find missing/duplicate in 1..n array" → cyclic sort, then scan for mismatch
- "Next permutation" → find rightmost dip, swap with just-larger, reverse suffix
- "Rearrange by condition" → two pointers with step 2 for alternating pattern
- "Rotate k positions in O(1) space" → 3 reverses
- "Mark visited without extra space (values 1..n)" → negate at index value-1
- "Place each value at correct index (1..n)" → cyclic sort
- "Find missing/duplicate in 1..n array" → cyclic sort, then scan for mismatch
- "Next permutation" → find rightmost dip, swap with just-larger, reverse suffix
- "Rearrange by condition" → two pointers with step 2 for alternating pattern