Coding Pattern Recognition Guide
How to spot which pattern to use, and how to apply it fast
HOW TO USE THIS GUIDE
When you read a problem, scan for the signals listed under each pattern. The first matching
pattern is usually correct. Brute force always works as a fallback if pattern recognition fails.
Probability of Each Pattern
Realistic odds of seeing each pattern in an intermediate coding assessment. Use this to
prioritize practice time.
Pattern Chance Priority
Hashmap 60% Very high
Two pointers 50% Very high
String manipulation 50% Very high
Single pass tracking 40% High
Sliding window 25-30% Moderate
Simple recursion 20% Moderate
Math / digits 20% Moderate
Sorting application 20% Moderate
Stack / queue 15% Low-moderate
Matrix / 2D array 10% Low
Probabilities don't add to 100% because problems often combine patterns. Master the top 4
first; cover the rest lightly if you have time.
1. Hashmap Counting
Use when you need to count, group, or check 'have I seen this before' across an array or string.
When to use it
Signal in problem Example phrasing
Frequency How many times does each letter appear?
Duplicates Does the array contain a duplicate?
Signal in problem Example phrasing
Grouping Group anagrams together
Pair lookup Find two numbers that add to target
Uniqueness First non-repeating character
How to apply it
# Counting frequencies
count = {}
for x in arr:
count[x] = [Link](x, 0) + 1
# Have I seen this?
seen = set()
for x in arr:
if x in seen:
return True
[Link](x)
# Pair lookup (two sum pattern)
seen = {}
for i, num in enumerate(nums):
complement = target - num
if complement in seen:
return [seen[complement], i]
seen[num] = i
TRICK
If the problem mentions "target sum" or "pair" — hashmap.
If you find yourself thinking about nested loops just to look something up — switch to
hashmap.
Always O(n) time, O(n) space.
1b. Hashset (Set)
Use when you only care WHETHER something exists, not how many times or where. Lighter
and faster than a hashmap when you don't need values.
When to use it
Signal in problem Example phrasing
Existence check Does this element appear in the array?
Deduplication Return the unique elements
Signal in problem Example phrasing
Intersection Find common elements between two arrays
Union/Difference Elements in A but not in B
Cycle detection Have I visited this node before?
Uniqueness rule Are all elements distinct?
How to apply it
# Has duplicates?
seen = set()
for x in arr:
if x in seen:
return True
[Link](x)
return False
# Remove duplicates (preserve order)
seen = set()
result = []
for x in arr:
if x not in seen:
[Link](x)
[Link](x)
# Intersection of two arrays
set_a = set(arr1)
return [x for x in arr2 if x in set_a]
# All unique?
return len(set(arr)) == len(arr)
TRICK
Hashmap vs Hashset: use a SET when you only need "is it there?"; use a MAP when you
need to associate a value (count, index, group).
set() lookup is O(1), same as dict — but uses less memory.
Common operations: set1 & set2 (intersection), set1 | set2 (union), set1 - set2 (difference).
2. Two Pointers
Use when working with sorted arrays, strings, or finding pairs/triplets where you can scan from
both ends.
When to use it
Signal in problem Example phrasing
Sorted input Given a sorted array...
Palindrome Is the string a palindrome?
Reverse Reverse the string in place
Pair in sorted Find pair summing to target (sorted)
Remove/dedupe Remove duplicates in place
Container/area Max area between two lines
How to apply it
# Palindrome check
left, right = 0, len(s) - 1
while left < right:
if s[left] != s[right]:
return False
left += 1
right -= 1
return True
# Pair sum in sorted array
left, right = 0, len(arr) - 1
while left < right:
total = arr[left] + arr[right]
if total == target:
return [left, right]
elif total < target:
left += 1
else:
right -= 1
TRICK
If the array is already sorted — strongly consider two pointers before hashmap.
If the problem mentions "in place" — two pointers is usually the answer.
Always O(n) time, O(1) space — better than hashmap for sorted data.
3. Sliding Window
Use when you need to find a contiguous subarray or substring meeting some condition.
When to use it
Signal in problem Example phrasing
Contiguous Longest substring of...
Subarray Maximum sum subarray of size k
No repeats Longest substring without repeating characters
Window condition Smallest subarray summing to at least target
K distinct Longest substring with at most K distinct characters
How to apply it
# Variable-size window
left = 0
result = 0
window_state = {} # or set, or count
for right in range(len(arr)):
# expand window: add arr[right] to state
window_state[arr[right]] = window_state.get(arr[right], 0) + 1
# shrink window while condition violated
while condition_broken(window_state):
window_state[arr[left]] -= 1
if window_state[arr[left]] == 0:
del window_state[arr[left]]
left += 1
# update result with current valid window
result = max(result, right - left + 1)
return result
TRICK
Keywords "contiguous", "subarray", "substring", "window" → sliding window.
If you'd otherwise need a nested loop checking ranges — sliding window converts O(n²) into
O(n).
Fixed window size K? Just slide one element at a time. Variable size? Expand right, shrink
left.
4. String Basics
Use when the problem is fundamentally about parsing, transforming, or building strings.
When to use it
Signal in problem Example phrasing
Parse input Given a CSV line, extract fields
Format output Format the time as HH:MM:SS
Transform Capitalize each word
Build result Compress "aaabbc" to "a3b2c1"
Validate Is this a valid IP address?
How to apply it
# Common string operations
s = "hello world"
chars = list(s) # to list
result = ''.join(chars) # back to string
words = [Link](' ') # split by space
parts = [Link](',') # split by comma
upper = [Link]() # case
stripped = [Link]() # remove whitespace
s = [Link]('a', 'b') # replace
# Build a string efficiently
result = []
for char in s:
if condition:
[Link](char)
return ''.join(result)
# Check character type
[Link](), [Link](), [Link](), [Link]()
TRICK
Never concatenate strings in a loop with +=. Use a list, then ''.join() at the end.
If you have to track position while building output, often combine with two pointers or a
counter.
split() with no argument splits on any whitespace.
5. Single-Pass Tracking
Use when you can compute the answer by scanning the input once while maintaining a small
amount of state.
When to use it
Signal in problem Example phrasing
Running max/min Find the maximum element
Running sum Compute the total
Single value Find the majority element
Best result so far Maximum profit from one transaction
Streak/run Longest consecutive sequence of equal values
How to apply it
# Running maximum
max_val = arr[0]
for x in arr[1:]:
if x > max_val:
max_val = x
# Best time to buy/sell (Kadane-like)
min_price = float('inf')
max_profit = 0
for price in prices:
if price < min_price:
min_price = price
elif price - min_price > max_profit:
max_profit = price - min_price
# Longest run of equal values
longest = 1
current = 1
for i in range(1, len(arr)):
if arr[i] == arr[i-1]:
current += 1
longest = max(longest, current)
else:
current = 1
TRICK
If you only need one number as the answer (max, min, count, sum) — almost always single
pass.
Keep state minimal: 1-3 variables, not a dict.
Always O(n) time, O(1) space — the most efficient pattern when applicable.
Quick Decision Tree
Read the problem twice, then ask these questions in order:
STEP 1 — DOES IT INVOLVE COUNTING OR LOOKUP?
Counting frequencies? → Hashmap
"Have I seen this?" → Set
Pair summing to target? → Hashmap (or two pointers if sorted)
Group by some key? → Hashmap of lists
STEP 2 — IS THE INPUT SORTED OR SCANNED FROM BOTH ENDS?
Sorted array + pair/triplet problem? → Two pointers
Palindrome check? → Two pointers
Reverse in place? → Two pointers
STEP 3 — IS THE ANSWER A CONTIGUOUS RANGE?
Longest/shortest substring or subarray with property? → Sliding window
Maximum sum of K consecutive elements? → Sliding window (fixed size)
Smallest range meeting condition? → Sliding window (variable size)
STEP 4 — IS IT ABOUT TRANSFORMING/PARSING TEXT?
Split, format, replace, validate? → String basics + maybe regex
Build result while scanning? → List append + ''.join()
STEP 5 — DO YOU JUST NEED ONE VALUE AT THE END?
Max, min, count, sum, average? → Single pass with 1-3 variables
Best result so far? → Single pass tracking current and best
Common Mistakes to Avoid
Performance traps
• Using x in list inside a loop — that's O(n) per lookup, making total O(n²). Use a set instead.
• Concatenating strings with += in a loop — O(n²). Use a list and ''.join() at the end.
• Calling [Link](x) inside a loop — same O(n²) trap. Build a position map first.
• Using [Link](0) — O(n) per call. Use [Link] if you need fast pop from front.
Edge cases to always check
• Empty input: [] or ""
• Single element: [x] or "x"
• All duplicates: [5, 5, 5, 5]
• Negative numbers (especially for sums and products)
• Very large input — does your O(n²) solution time out?
Code style for the assessment
• Read the problem twice before writing any code
• Write the brute force first if you're stuck. A working slow solution beats a broken fast one
• Test mentally against the given examples before submitting
• Add a one-line complexity comment if you're confident: # Time: O(n), Space: O(n)
• Don't over-engineer. No classes for a 20-line problem. No design patterns.
The 5-Pattern Mental Checklist
Memorize this. When you see a problem, run through the list in order:
1. Hashmap — counting, lookup, "seen before", pair-sum
2. Two pointers — sorted input, palindromes, reverse in place
3. Sliding window — contiguous subarray or substring with condition
4. String basics — parse, transform, build output text
5. Single pass — running max/min/sum/count, one value answer
REMEMBER
If none of these patterns clicks, write the brute force solution first. It almost always works for
small inputs and gets you partial credit. You can optimize after if time permits — but a
working brute force is better than nothing.