Most candidates approach coding interviews the wrong way.
They memorize hundreds of individual problems. Grinding through LeetCode, trying to cover every possible question they might face.
But here's the secret top performers know: Most coding problems follow recognizable patterns.
Master these 10 patterns, and you'll be able to solve 80% of interview questions—even ones you've never seen before.
Instead of memorizing 500 problems, you'll understand the core concepts that unlock thousands of variations.
It's the difference between memorizing answers and understanding how to think.
Why Patterns Matter
Think of algorithm patterns like chess openings.
You don't memorize every possible chess game—you learn strategic patterns that apply to thousands of games.
The same principle applies to coding interviews.
When you see a new problem, pattern recognition helps you immediately identify the approach. "This looks like a sliding window problem," you think, and suddenly you know exactly where to start.
No more blank stares. No more panic.
Benefits of pattern-based learning:
Solve new problems faster
Instead of staring blankly at an unfamiliar problem, you'll recognize the underlying pattern and apply the template you've practiced. First 30 seconds: problem identified.
Recognize variations of known problems
Most "new" interview questions are just variations of classic problems.
Patterns help you see through the disguise. They can reword it however they want—you'll still spot the pattern.
Build true problem-solving intuition
With patterns, you develop a sixth sense for which approach will work best—even before you start coding.
It's like the Matrix. Once you see the patterns, you can't unsee them.
Reduce interview stress
There's nothing more calming than thinking, "I've solved problems like this before!"
Pattern knowledge gives you confidence. And confidence shows.
Pattern #1: Two Pointers
The two pointers pattern is one of the most elegant techniques in your algorithmic toolkit. It uses two reference points that move through the data structure to find relationships or satisfy conditions.
When to use: Problems involving arrays, strings, or linked lists where you need to find pairs, triplets, or subarrays.
Key indicators:
When you see these phrases in a problem, think "two pointers":
"Find pair that sums to X" - Classic two pointers from both ends of a sorted array.
"Remove duplicates in sorted array" - One pointer reads, another writes unique values.
"Reverse a string" - Pointers start at opposite ends and swap inward.
"Container with most water" - Pointers maximize area by moving strategically.
Basic structure:
def two_pointers_template(arr):
left = 0
right = len(arr) - 1
while left < right:
# Calculate something with arr[left] and arr[right]
if condition_met:
return result
elif left_should_move:
left += 1
else:
right -= 1
return result
Example problem: Two Sum (sorted array)
def two_sum_sorted(numbers, target):
"""
Find two numbers that add up to target in sorted array.
Time: O(n), Space: O(1)
"""
left, right = 0, len(numbers) - 1
while left < right:
current_sum = numbers[left] + numbers[right]
if current_sum == target:
return [left, right]
elif current_sum < target:
left += 1 # Need bigger sum
else:
right -= 1 # Need smaller sum
return []
# Test
print(two_sum_sorted([1, 2, 3, 4, 6], 6)) # [1, 3] → 2+4=6
More problems to practice:
- 3Sum
- Remove Nth Node From End
- Trapping Rain Water
- Valid Palindrome
Pattern #2: Sliding Window
The sliding window pattern is perfect for problems involving contiguous sequences. Imagine a window sliding across your array or string, expanding and contracting as needed to find the optimal solution.
When to use: Problems involving subarrays or substrings with specific conditions.
Key indicators:
These problem descriptions scream "sliding window":
"Longest/shortest substring with..." - Window expands to find longest, contracts to find shortest.
"Maximum sum subarray of size K" - Fixed-size window slides to find maximum sum.
"Find all anagrams" - Window tracks character frequency to match patterns.
"Minimum window substring" - Dynamic window finds smallest substring containing all required characters.
Two types:
- Fixed size: Window size is constant
- Dynamic size: Window grows and shrinks
Fixed window template:
def fixed_sliding_window(arr, k):
window_sum = sum(arr[:k])
max_sum = window_sum
for i in range(k, len(arr)):
# Slide the window
window_sum = window_sum - arr[i - k] + arr[i]
max_sum = max(max_sum, window_sum)
return max_sum
Dynamic window template:
def dynamic_sliding_window(s, condition):
left = 0
result = float('inf')
current_state = {}
for right in range(len(s)):
# Expand window by including s[right]
# Update current_state
while condition_met:
# Update result if needed
# Shrink window from left
left += 1
return result
Example problem: Longest Substring Without Repeating Characters
def length_of_longest_substring(s):
"""
Find length of longest substring without repeating characters.
Time: O(n), Space: O(min(n, m)) where m is charset size
"""
char_set = set()
left = 0
max_length = 0
for right in range(len(s)):
# Shrink window until no duplicates
while s[right] in char_set:
char_set.remove(s[left])
left += 1
# Add current character
char_set.add(s[right])
max_length = max(max_length, right - left + 1)
return max_length
# Test
print(length_of_longest_substring("abcabcbb")) # 3 (abc)
print(length_of_longest_substring("bbbbb")) # 1 (b)
More problems to practice:
- Maximum Sum Subarray of Size K
- Fruits Into Baskets
- Permutation in String
- Minimum Window Substring
Pattern #3: Fast & Slow Pointers
When to use: Problems involving cycles or finding middle elements in linked lists.
Key indicators:
- "Detect cycle"
- "Find middle element"
- "Happy number"
- "Start of cycle"
Template:
def fast_slow_pointers(head):
slow = head
fast = head
while fast and fast.next:
slow = slow.next # Move 1 step
fast = fast.next.next # Move 2 steps
if slow == fast:
return True # Cycle detected
return False # No cycle
Example problem: Linked List Cycle
class ListNode:
def __init__(self, val=0):
self.val = val
self.next = None
def has_cycle(head):
"""
Detect if linked list has a cycle.
Time: O(n), Space: O(1)
"""
if not head or not head.next:
return False
slow = head
fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if slow == fast:
return True
return False
Example problem: Middle of Linked List
def find_middle(head):
"""
Find middle node of linked list.
When fast reaches end, slow is at middle.
Time: O(n), Space: O(1)
"""
slow = fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
return slow
More problems to practice:
- Happy Number
- Start of LinkedList Cycle
- Palindrome LinkedList
Pattern #4: Merge Intervals
When to use: Problems with overlapping intervals or ranges.
Key indicators:
- "Merge overlapping intervals"
- "Insert interval"
- "Meeting rooms"
- "Conflicting appointments"
Template:
def merge_intervals(intervals):
if not intervals:
return []
# Sort by start time
intervals.sort(key=lambda x: x[0])
merged = [intervals[0]]
for current in intervals[1:]:
last = merged[-1]
if current[0] <= last[1]: # Overlapping
# Merge by updating end time
last[1] = max(last[1], current[1])
else:
merged.append(current)
return merged
Example problem: Merge Intervals
def merge(intervals):
"""
Merge all overlapping intervals.
Time: O(n log n), Space: O(n)
"""
if not intervals:
return []
intervals.sort(key=lambda x: x[0])
merged = [intervals[0]]
for current in intervals[1:]:
if current[0] <= merged[-1][1]:
# Overlapping - merge
merged[-1][1] = max(merged[-1][1], current[1])
else:
# Non-overlapping - add new interval
merged.append(current)
return merged
# Test
print(merge([[1,3],[2,6],[8,10],[15,18]]))
# [[1,6],[8,10],[15,18]]
More problems to practice:
- Insert Interval
- Intervals Intersection
- Meeting Rooms II
- Employee Free Time
Pattern #5: Cyclic Sort
When to use: Problems with arrays containing numbers in a given range.
Key indicators:
- "Find missing number in range [1, n]"
- "Find duplicate number"
- "Find all duplicates"
- Numbers are in range [0, n] or [1, n]
Template:
def cyclic_sort(nums):
i = 0
while i < len(nums):
correct_index = nums[i] - 1 # For range [1, n]
# OR: correct_index = nums[i] # For range [0, n-1]
if nums[i] != nums[correct_index]:
# Swap to correct position
nums[i], nums[correct_index] = nums[correct_index], nums[i]
else:
i += 1
return nums
Example problem: Find Missing Number
def find_missing_number(nums):
"""
Find missing number in array [0, 1, ..., n].
Time: O(n), Space: O(1)
"""
i, n = 0, len(nums)
# Place each number at its correct index
while i < n:
correct_index = nums[i]
if nums[i] < n and nums[i] != nums[correct_index]:
nums[i], nums[correct_index] = nums[correct_index], nums[i]
else:
i += 1
# Find first missing number
for i in range(n):
if nums[i] != i:
return i
return n
# Test
print(find_missing_number([4, 0, 3, 1])) # 2
print(find_missing_number([8, 3, 5, 2, 4, 6, 0, 1])) # 7
More problems to practice:
- Find All Duplicates
- Find Corrupt Pair
- First Missing Positive
Pattern #6: In-place Reversal of LinkedList
When to use: Problems requiring reversal of linked lists.
Key indicators:
- "Reverse a linked list"
- "Reverse every K-element sub-list"
- "Rotate a linked list"
Template:
def reverse_linked_list(head):
prev = None
current = head
while current:
next_node = current.next # Save next
current.next = prev # Reverse link
prev = current # Move prev forward
current = next_node # Move current forward
return prev # New head
Example problem: Reverse LinkedList
def reverse_list(head):
"""
Reverse entire linked list.
Time: O(n), Space: O(1)
"""
prev = None
current = head
while current:
# Save next node
next_node = current.next
# Reverse the link
current.next = prev
# Move pointers forward
prev = current
current = next_node
return prev
Example problem: Reverse Sublist
def reverse_between(head, left, right):
"""
Reverse sublist from position left to right.
Time: O(n), Space: O(1)
"""
if not head or left == right:
return head
dummy = ListNode(0)
dummy.next = head
prev = dummy
# Move to start position
for _ in range(left - 1):
prev = prev.next
# Reverse the sublist
current = prev.next
for _ in range(right - left):
next_node = current.next
current.next = next_node.next
next_node.next = prev.next
prev.next = next_node
return dummy.next
More problems to practice:
- Reverse Every K-element Sub-list
- Rotate a LinkedList
Pattern #7: Tree BFS (Breadth-First Search)
Breadth-First Search explores a tree level by level, like ripples spreading across water. It's perfect for problems that care about tree levels or need to find the shortest path in an unweighted tree.
When to use: Problems requiring level-order traversal of trees.
Key indicators:
Watch for these tree problem descriptions:
"Level order traversal" - Visit nodes level by level from top to bottom.
"Zigzag traversal" - Alternate direction for each level (left-to-right, then right-to-left).
"Minimum depth" - BFS finds the shortest path to a leaf node efficiently.
"Connect level order siblings" - Link nodes on the same level together.
Template:
from collections import deque
def level_order_traversal(root):
if not root:
return []
result = []
queue = deque([root])
while queue:
level_size = len(queue)
current_level = []
for _ in range(level_size):
node = queue.popleft()
current_level.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
result.append(current_level)
return result
More problems to practice:
- Binary Tree Zigzag Level Order
- Minimum Depth of Binary Tree
- Right View of Binary Tree
Pattern #8: Tree DFS (Depth-First Search)
When to use: Tree problems requiring path traversal.
Key indicators:
- "Path sum"
- "All paths"
- "Diameter of tree"
- "Maximum depth"
Three traversal types:
def inorder(root): # Left, Root, Right
if not root:
return []
return inorder(root.left) + [root.val] + inorder(root.right)
def preorder(root): # Root, Left, Right
if not root:
return []
return [root.val] + preorder(root.left) + preorder(root.right)
def postorder(root): # Left, Right, Root
if not root:
return []
return postorder(root.left) + postorder(root.right) + [root.val]
Example problem: Path Sum
def has_path_sum(root, target_sum):
"""
Check if tree has path with given sum.
Time: O(n), Space: O(h) for recursion
"""
if not root:
return False
# Leaf node - check if sum matches
if not root.left and not root.right:
return root.val == target_sum
# Recursively check left and right subtrees
remaining = target_sum - root.val
return (has_path_sum(root.left, remaining) or
has_path_sum(root.right, remaining))
More problems to practice:
- All Paths for Sum
- Sum of Path Numbers
- Path With Maximum Sum
Pattern #9: Two Heaps
When to use: Problems involving finding median or scheduling.
Key indicators:
- "Find median"
- "Sliding window median"
- "Maximize capital"
Template:
import heapq
class MedianFinder:
def __init__(self):
self.small = [] # Max heap (invert values)
self.large = [] # Min heap
def add_num(self, num):
# Add to max heap (small)
heapq.heappush(self.small, -num)
# Balance: move largest from small to large
heapq.heappush(self.large, -heapq.heappop(self.small))
# If large has more elements, rebalance
if len(self.large) > len(self.small):
heapq.heappush(self.small, -heapq.heappop(self.large))
def find_median(self):
if len(self.small) > len(self.large):
return -self.small[0]
return (-self.small[0] + self.large[0]) / 2.0
More problems to practice:
- Sliding Window Median
- IPO (Maximize Capital)
Pattern #10: Modified Binary Search
When to use: Sorted or rotated arrays, finding ranges.
Key indicators:
- "Search in sorted array"
- "Find rotation point"
- "Search in rotated array"
- "Find range [start, end]"
Template:
def binary_search(arr, target):
left, right = 0, len(arr) - 1
while left <= right:
mid = left + (right - left) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
left = mid + 1
else:
right = mid - 1
return -1
Example problem: Search in Rotated Array
def search_rotated(nums, target):
"""
Search in rotated sorted array.
Time: O(log n), Space: O(1)
"""
left, right = 0, len(nums) - 1
while left <= right:
mid = left + (right - left) // 2
if nums[mid] == target:
return mid
# Determine which half is sorted
if nums[left] <= nums[mid]:
# Left half is sorted
if nums[left] <= target < nums[mid]:
right = mid - 1
else:
left = mid + 1
else:
# Right half is sorted
if nums[mid] < target <= nums[right]:
left = mid + 1
else:
right = mid - 1
return -1
# Test
print(search_rotated([4,5,6,7,0,1,2], 0)) # 4
More problems to practice:
- Find Minimum in Rotated Array
- Search Insert Position
- Find Peak Element
How to Practice These Patterns
Learning patterns is just the first step. Mastery comes from deliberate, structured practice that builds both pattern recognition and implementation speed.
Week 1-2: Learn the Patterns
Start with the fundamentals—understanding beats memorization:
Study one pattern per day. Deep dive into the pattern's mechanics, when to use it, and common variations.
Understand the template. Don't just copy code—understand why each line exists and what problem it solves.
Solve 2-3 easy problems per pattern. Apply the template to simple problems until it feels natural.
Week 3-4: Practice Variations
- Solve medium problems
- Mix patterns (some problems use multiple patterns)
- Time yourself
Week 5-6: Master Advanced Problems
- Tackle hard problems
- Do mock interviews
- Review and optimize solutions
Daily Practice Routine
Day 1: Two Pointers (3 problems)
Day 2: Sliding Window (3 problems)
Day 3: Fast & Slow Pointers (3 problems)
Day 4: Review + Mock Interview
Day 5: Merge Intervals (3 problems)
Day 6: Cyclic Sort (3 problems)
Day 7: Rest or Review mistakes
Pattern Recognition Cheatsheet
Use this quick reference during practice to identify which pattern applies to new problems. With time, pattern recognition becomes automatic.
| If problem mentions... | Consider pattern... |
|---|---|
| Sorted array/string | Two Pointers, Binary Search |
| Pairs/triplets | Two Pointers |
| Subarray/substring | Sliding Window |
| Linked list cycle | Fast & Slow Pointers |
| Overlapping intervals | Merge Intervals |
| Numbers in range [1,n] | Cyclic Sort |
| Reverse linked list | In-place Reversal |
| Tree level order | BFS |
| Tree paths | DFS |
| Find median | Two Heaps |
| Search in sorted | Binary Search |
Using AI for Pattern Practice
Modern AI tools can accelerate your learning by providing instant feedback and guidance. It's like having a senior engineer mentor available 24/7.
Interview Whisper helps you:
Identify which pattern applies to a new problem. See a problem and not sure where to start? The AI can recognize the pattern instantly and point you in the right direction.
Suggest the right template when you're stuck. No need to flip through notes—get the relevant template with explanations on demand.
Point out optimization opportunities. Your brute-force solution works, but the AI can suggest how to optimize it from O(n²) to O(n).
Provide real-time hints during practice. Stuck on a specific step? Get contextual hints that help you learn without giving away the entire solution.
Example interaction:
You: "I need to find the longest substring without duplicates"
AI: "This is a Sliding Window pattern. Use two pointers and a set
to track characters. Expand right, shrink left when duplicate found."
Conclusion
Instead of memorizing 500 individual problems, master these 10 patterns:
- ✅ Two Pointers - Pairs and triplets
- ✅ Sliding Window - Subarrays and substrings
- ✅ Fast & Slow Pointers - Cycles and middle elements
- ✅ Merge Intervals - Overlapping ranges
- ✅ Cyclic Sort - Numbers in given range
- ✅ In-place Reversal - LinkedList reversal
- ✅ Tree BFS - Level order traversal
- ✅ Tree DFS - Path problems
- ✅ Two Heaps - Find median
- ✅ Modified Binary Search - Sorted arrays
With these patterns, you'll recognize the approach for most interview problems within seconds.
Ready to practice with AI guidance? Download Interview Whisper for Windows and macOS and get real-time pattern recognition help during your coding practice. Our AI identifies patterns, suggests templates, and helps you think like a top-tier engineer.
Explore our pricing plans to unlock unlimited practice sessions and advanced features.
Related Articles:
- 7 Common Coding Interview Mistakes and How to Avoid Them
- Top 10 Google Interview Questions and How to Answer Them
- Top 10 Behavioral Interview Questions
- Interview Whisper Success Stories
Practice Resources:
Need help? Contact our support team for personalized guidance.