Coding interview patterns are reusable algorithmic blueprints that map large families of problems to a small set of well-understood techniques. Mastering these patterns matters because interviewers at top companies deliberately recycle the same underlying structures: recognizing the pattern instantly is the difference between a clean O(n) solution and a frustrated brute-force attempt. The key insight is that pattern recognition, not memorization, is the skill being tested: the same two-pointer template that solves "pair sum in sorted array" also solves "container with most water" and "3Sum". Each pattern below includes the canonical template, the signal that tells you to apply it, and the complexity you should expect to quote.
What This Cheat Sheet Covers
This topic spans 16 focused tables and 105 indexed concepts, 87 flashcards, 5 practice tests with 134 questions. Below is a complete table-by-table outline of this topic, spanning foundational concepts through advanced details.
A jump-to index of every table row in this cheat sheet.
An interactive map of every table and concept in this topic.
Table 1: Two Pointers
Two pointers place one pointer at each end of a sorted (or partitioned) array and move them toward each other based on a condition, eliminating brute-force O(n²) pair enumeration. A second variant uses both pointers moving in the same direction for partitioning or fast/slow detection; that variant is covered separately in Table 3.
| Technique | Example | Description | |
|---|---|---|---|
l, r = 0, len(arr)-1while l < r: if arr[l]+arr[r]==target: return [l,r] elif arr[l]+arr[r]<target: l+=1 else: r-=1 | • Works on sorted arrays • shrink the window from both ends based on whether the sum is too small or too large | ||
nums.sort()for i in range(len(nums)-2): l, r = i+1, len(nums)-1 # two-pointer inner loop | • Fix one element, then run opposite-direction two pointers on the remainder • reduces O(n³) → O(n²). | ||
slow = 0for fast in range(1, len(nums)): if nums[fast] != nums[slow]: slow += 1 nums[slow] = nums[fast] | • slow marks the boundary of the valid prefix• fast scans ahead, the classic same-direction two pointers setup for in-place array compaction | ||
l, r = 0, len(h)-1res = 0while l < r: res = max(res, min(h[l],h[r])*(r-l)) if h[l] < h[r]: l += 1 else: r -= 1 | • Doesn't need a sorted array, just a height comparison • Always move the pointer at the shorter height inward: moving the taller one can only reduce area. | ||
l_max = r_max = 0; l, r = 0, n-1while l < r: if h[l]<=h[r]: l_max=max(l_max,h[l]); water+=l_max-h[l]; l+=1 else: r_max=max(r_max,h[r]); water+=r_max-h[r]; r-=1 | • Maintain running max from each side • water at position = min(left_max, right_max) - height[i]. Two-pointer runs in O(n) time, O(1) space vs O(n) space prefix-array approach | ||
l, r = 0, len(s)-1while l < r: if s[l] != s[r]: return False l += 1; r -= 1return True | • Compare characters from both ends • early exit on mismatch, O(n) time, O(1) space |