Pattern Recognition & Problem-Solving Strategy
📖 Concept
Pattern recognition is the meta-skill that separates senior engineers from those who just memorize solutions. Instead of solving each problem from scratch, you match it to a known pattern.
Core patterns and their triggers:
1. Sliding Window — Subarray/substring with condition
- Trigger: "contiguous subarray", "substring", "window of size K"
- Template: Two pointers (left, right) expanding right, shrinking left
2. Two Pointers — Sorted array, pair finding
- Trigger: "sorted array", "pair that sums to", "in-place"
- Template: left=0, right=end, move based on comparison
3. BFS — Shortest path, level-order
- Trigger: "shortest", "minimum steps", "level by level", "unweighted graph"
- Template: Queue + visited set
4. DFS / Backtracking — All combinations, permutations
- Trigger: "all possible", "generate all", "combinations", "subsets"
- Template: Recursive with state, undo state on backtrack
5. Dynamic Programming — Optimal substructure + overlapping subproblems
- Trigger: "minimum/maximum", "number of ways", "can you reach"
- Template: Define state, recurrence relation, base case
6. Binary Search — Sorted data, search space reduction
- Trigger: "sorted", "minimum that satisfies", "search space"
- Template: lo, hi, mid, adjust based on condition
7. Monotonic Stack — Next greater/smaller element
- Trigger: "next greater", "stock span", "histogram"
- Template: Stack of indices, pop when current > top
8. Union-Find — Connected components, grouping
- Trigger: "connected", "components", "cycle in undirected graph"
- Template: parent array, find with path compression, union by rank
💻 Code Example
1// Pattern matching examples23// PATTERN: When you see "subarray with sum = K" → Prefix sum + HashMap4fun subarraySum(nums: IntArray, k: Int): Int {5 val prefixCount = mutableMapOf(0 to 1) // prefix_sum → count6 var sum = 07 var count = 08 for (num in nums) {9 sum += num10 count += prefixCount.getOrDefault(sum - k, 0)11 prefixCount[sum] = prefixCount.getOrDefault(sum, 0) + 112 }13 return count14}15// Trigger identified: "subarray" + "sum equals K"16// Pattern: Prefix sum with HashMap1718// PATTERN: When you see "generate all subsets" → Backtracking19fun subsets(nums: IntArray): List<List<Int>> {20 val result = mutableListOf<List<Int>>()2122 fun backtrack(start: Int, current: MutableList<Int>) {23 result.add(current.toList()) // Add current subset24 for (i in start until nums.size) {25 current.add(nums[i]) // Choose26 backtrack(i + 1, current) // Explore27 current.removeAt(current.lastIndex) // Un-choose28 }29 }3031 backtrack(0, mutableListOf())32 return result33}3435// PATTERN: When you see "K-th largest" → Min-heap of size K36fun findKthLargest(nums: IntArray, k: Int): Int {37 val minHeap = PriorityQueue<Int>() // Min-heap38 for (num in nums) {39 minHeap.offer(num)40 if (minHeap.size > k) minHeap.poll() // Remove smallest41 }42 return minHeap.peek() // K-th largest is at top43}44// O(n log k) time, O(k) space4546// PATTERN: When you see "minimum in rotated sorted" → Modified binary search47fun findMin(nums: IntArray): Int {48 var lo = 049 var hi = nums.lastIndex50 while (lo < hi) {51 val mid = lo + (hi - lo) / 252 if (nums[mid] > nums[hi]) lo = mid + 153 else hi = mid54 }55 return nums[lo]56}
🏋️ Practice Exercise
Pattern Recognition Drill: For each problem, identify the pattern BEFORE solving:
- "Find all anagrams in a string" → ? (Sliding window + frequency map)
- "Minimum number of jumps to reach end" → ? (Greedy / BFS)
- "Clone a graph" → ? (BFS + HashMap)
- "Coin change — minimum coins" → ? (DP — bottom-up)
- "Find celebrity in a party" → ? (Two pointers / elimination)
- "Merge K sorted lists" → ? (Min-heap)
- "Longest palindromic substring" → ? (Expand around center / DP)
- "Number of islands" → ? (BFS/DFS grid traversal)
- "Decode ways" → ? (Linear DP — fibonacci variant)
- "Task scheduler with cooldown" → ? (Greedy + math / max-heap)
⚠️ Common Mistakes
Memorizing solutions without understanding the pattern — different inputs will break your memorized approach
Forcing a pattern that doesn't fit — if two pointers doesn't work, consider sliding window or hashmap
Not recognizing DP problems — the triggers are 'optimal' (min/max), 'count ways', and overlapping subproblems
Using DFS when BFS is needed — BFS guarantees shortest path in unweighted graphs, DFS does not
💼 Interview Questions
🎤 Mock Interview
Mock interview is powered by AI for Pattern Recognition & Problem-Solving Strategy. Login to unlock this feature.