Coding Interview Framework: Step-by-Step Problem Solving
π― The UMPIRE Method
A proven framework used by engineers at Google, Meta, and Amazon:
U - Understand the problem
M - Match to known patterns
P - Plan the solution
I - Implement the code
R - Review / test
E - Evaluate complexity
Step 1: Understand (3-5 minutes)
Questions to Ask
Input/Output:
- What are the inputs? What type? What size?
- What is the expected output format?
- Can the input be empty/null?
Constraints:
- What are the time/space constraints?
- Are there memory limits?
- Is the input sorted? Contains duplicates?
Edge Cases:
- Empty input
- Single element
- All same elements
- Negative numbers
- Very large input (overflow?)
Examples:
- Walk through 1-2 examples from the problem
- Create your own example that tests edge cases
Template Questions Script
"Before I start, let me clarify a few things:
1. Can the input array be empty?
2. Are there negative numbers?
3. Can there be duplicates?
4. What should I return if there's no valid answer?
5. Is the input sorted?"
Step 2: Match (2-3 minutes)
Pattern Recognition Checklist
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β PATTERN MATCHING FLOWCHART β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β Is input sorted? β
β βββ Yes β Two Pointers / Binary Search β
β βββ No β Continue... β
β β
β Need contiguous subarray/substring? β
β βββ Yes β Sliding Window β
β βββ No β Continue... β
β β
β Need to find pairs with condition? β
β βββ Yes β Hash Map / Two Pointers β
β βββ No β Continue... β
β β
β Tree/graph traversal? β
β βββ Level-by-level β BFS β
β βββ All paths β DFS + Backtracking β
β βββ Shortest path β BFS (unweighted) / Dijkstra β
β β
β Need all combinations/permutations? β
β βββ Yes β Backtracking β
β βββ No β Continue... β
β β
β Optimal substructure + overlapping subproblems? β
β βββ Yes β Dynamic Programming β
β βββ No β Continue... β
β β
β Need K largest/smallest? β
β βββ Yes β Heap (Priority Queue) β
β βββ No β Continue... β
β β
β Dependencies between tasks? β
β βββ Yes β Topological Sort β
β βββ No β Continue... β
β β
β Connected components? β
β βββ Yes β Union Find / BFS/DFS β
β βββ No β Continue... β
β β
β Next greater/smaller element? β
β βββ Yes β Monotonic Stack β
β βββ No β Brute force, then optimize β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Step 3: Plan (3-5 minutes)
Always Start with Brute Force
"I'll start with a brute force approach, then optimize."
Brute Force: O(nΒ²) or O(nΒ³)
βββ Identify the bottleneck
βββ Ask: Can I use a hash map for O(1) lookup?
βββ Ask: Can I sort first to use two pointers?
βββ Ask: Can I use a heap for top-K?
βββ Ask: Can I use DP to avoid recomputation?
Discuss Trade-offs
"I see two approaches:
1. [Approach A]: O(n) time, O(n) space - uses extra hash map
2. [Approach B]: O(n log n) time, O(1) space - sort first
I'd go with [Approach A/B] because [reasoning about constraints]."
Write Pseudocode
# Pseudocode (don't write real code yet)
def solve(input):
# 1. Initialize data structure
# 2. Process input in loop
# 3. Update result
# 4. Return answer
Step 4: Implement (15-20 minutes)
Code Quality Checklist
# β
Good
def twoSum(nums, target):
seen = {} # value -> index
for i, num in enumerate(nums):
complement = target - num
if complement in seen:
return [seen[complement], i]
seen[num] = i
return [] # No solution found
# β Bad
def f(a, t):
d = {}
for i in range(len(a)):
if t-a[i] in d:
return [d[t-a[i]], i]
d[a[i]] = i
Best Practices
- Descriptive variable names β
left,right, notl,r - Consistent naming β camelCase or snake_case, not mixed
- Break into helper functions β Especially for recursive solutions
- Handle edge cases early β Return immediately for empty/null
- Comment tricky parts β Not every line, just the non-obvious
Implementation Template
def solution(input):
# Edge case
if not input:
return default_value
# Initialize
data_structure = ...
result = ...
# Main logic
for element in input:
# Process
...
return result
Step 5: Review / Test (5 minutes)
Walk Through Your Code
Pick a test case and trace through every line:
Input: [2, 7, 11, 15], target = 9
i=0: num=2, complement=7, seen={} β not found, seen={2:0}
i=1: num=7, complement=2, seen={2:0} β found! return [0, 1]
β Correct!
Test Cases to Walk Through
- Normal case β Typical input
- Edge case β Empty, single element
- Boundary β Min/max values
- Special β All same, sorted reverse, etc.
Common Bugs to Check
β‘ Off-by-one errors (<= vs <, length-1)
β‘ Integer overflow (use long for large numbers)
β‘ Null/empty handling
β‘ Modifying collection while iterating
β‘ Missing return statement
β‘ Wrong variable in loop (i vs j)
β‘ Not resetting state between iterations
Step 6: Evaluate (2 minutes)
State Complexity
"Let me analyze the complexity:
- Time: O(n) because we iterate through the array once
- Space: O(n) for the hash map in the worst case"
Discuss Optimizations
"If we had more time / different constraints:
- We could sort first for O(1) space but O(n log n) time
- We could use bit manipulation if the range was limited
- We could parallelize for very large inputs"
π― Framework in Action: Example Problem
Problem: Longest Substring Without Repeating Characters
Step 1: Understand
"Let me clarify:
- Input is a string
- I need to find the longest substring with no repeating characters
- Can the string be empty? (Yes β return 0)
- Only lowercase? (Clarify with interviewer)
- Example: 'abcabcbb' β 'abc' β length 3"
Step 2: Match
"This is a contiguous substring problem β Sliding Window pattern.
I'll use a hash set to track characters in the current window."
Step 3: Plan
"Approach: Sliding Window with hash set
- Expand right pointer, add character to set
- If character already in set, shrink from left until removed
- Track max window size
Time: O(n), Space: O(min(n, m)) where m is charset size"
Step 4: Implement
def lengthOfLongestSubstring(s):
char_set = set()
left = 0
max_length = 0
for right in range(len(s)):
while s[right] in char_set:
char_set.remove(s[left])
left += 1
char_set.add(s[right])
max_length = max(max_length, right - left + 1)
return max_length
Step 5: Review
"Let me trace 'abcabcbb':
right=0: 'a' not in set, add, window='a', max=1
right=1: 'b' not in set, add, window='ab', max=2
right=2: 'c' not in set, add, window='abc', max=3
right=3: 'a' in set, remove 'a' (left=0), left=1, add 'a', window='bca', max=3
... continues correctly
Edge case: '' β returns 0 β
Edge case: 'bbbb' β returns 1 β"
Step 6: Evaluate
"Time: O(n) β each character is visited at most twice (once by right, once by left)
Space: O(min(n, m)) β the set holds at most min(n, charset_size) characters"
β οΈ Common Interview Mistakes
Technical Mistakes
- Jumping to code without understanding the problem
- Starting with optimal instead of brute force
- Not handling edge cases (empty input, null, single element)
- Off-by-one errors in loop bounds
- Modifying input when it should be preserved
- Integer overflow with large numbers
Communication Mistakes
- Silent coding β Always explain your thought process
- Not asking questions β Shows you assume instead of clarify
- Ignoring hints β Interviewers give hints for a reason
- Arguing with interviewer β Theyβre trying to help
- Giving up too quickly β Show you can work through difficulty
Process Mistakes
- No testing β Always walk through at least one test case
- No complexity analysis β Always state time and space
- Spending too long on one approach β Know when to pivot
- Not discussing trade-offs β Shows depth of understanding
π Cross-References
- Problem Patterns β Match problems to patterns in Step 2
- Data Structures β Choose the right structure in Step 3
- Complexity Analysis β Analyze in Step 6
- System Design Framework β Similar structured approach for design