## Two Pointers Walk two indices instead of trying all pairs — **order lets you prune O(n²) → O(n)**. --- ## Recognition - Sorted array + pair/target condition → converge from both ends - Palindrome / symmetric check → ends inward - In-place partition or dedupe → slow writer + fast reader - Two sequences compared → one pointer each --- ## Template — converging (LC 167) ```js function twoSumSorted(nums, target) { let l = 0; let r = nums.length - 1; while (l < r) { const sum = nums[l] + nums[r]; if (sum === target) return [l + 1, r + 1]; if (sum < target) l++; // need a bigger sum else r--; // need a smaller sum } } ``` Each step discards every pair using the abandoned index — that's the proof. --- ## Template — fast/slow writer (LC 977 idea) ```js function sortedSquares(nums) { const out = new Array(nums.length); let l = 0; let r = nums.length - 1; for (let i = nums.length - 1; i >= 0; i--) { const a = nums[l] * nums[l]; const b = nums[r] * nums[r]; if (a > b) { out[i] = a; l++; } else { out[i] = b; r--; } } return out; } ``` Largest squares live at the **edges** — fill the output backwards. --- ## Pitfalls - Moving the wrong pointer breaks the pruning argument - Duplicates in 3Sum: skip repeats after each fixed element - `l < r` vs `l <= r`: do the pointers meet or cross? --- ## Recall - Container With Most Water: why move the *shorter* wall? - 3Sum = sort + fix one + which pattern inside? - Valid Palindrome: what do you do with non-alphanumerics? --- ## Drill - 125 Valid Palindrome · 167 Two Sum II - 15 3Sum · 11 Container With Most Water - 42 Trapping Rain Water · 392 Is Subsequence - 977 Squares of a Sorted Array · 80 Remove Duplicates II