Interviewing
The interview problem-solving process
Clarify, work examples, state a brute force, then optimize, code, test and analyze. Interviewers grade the path.
Coding interviews compress judgment into about 45 minutes. The score is rarely "did you remember the clever trick." It is whether you clarify, pick a workable approach, write correct code, test it and talk like someone a teammate would trust. Use the same sequence every time until it is muscle memory.
Concept
Time complexity is how runtime grows as input size n grows. O(n) means roughly proportional to n; O(n²) means nested work over pairs. Interviewers want the big-O of your solution and a sentence on why.
Walking through it
- Clarify. Restate the problem. Ask about input size, duplicates, sortedness, mutability, nulls and what to return on empty input. Confirm examples.
- Work examples. Walk one happy path and one edge case before coding.
- Brute force. State a correct slow approach and its complexity. This proves you understand the problem and gives you a fallback.
- Optimize. Name the bottleneck (usually nested loops or repeated scans). Reach for a known pattern.
- Code. Write cleanly in your strongest interview language. Name variables for meaning.
- Test. Dry-run the code on your examples. Fix bugs out loud.
- Analyze. State time and space. Mention follow-ups if time remains.
Budget roughly: 5 minutes clarify + examples, 5–8 minutes approach, 20–25 minutes code, 5–7 minutes test and analyze. Going silent for ten minutes while searching for the optimal solution is worse than coding a correct O(n²) approach and then improving it.
Example
Given a sorted array, return indices of two numbers that sum to target.
Clarify: one solution? 0-indexed? duplicates?
Brute force: all pairs — O(n²).
Optimize: sorted → two pointers from the ends. Sum too small, move left up; too big, move right down — O(n) time, O(1) space.
Dry-run [2,7,11,15], target=9 → indices of 2 and 7.
def two_sum_sorted(nums: list[int], target: int) -> list[int]:
lo, hi = 0, len(nums) - 1
while lo < hi:
s = nums[lo] + nums[hi]
if s == target:
return [lo, hi]
if s < target:
lo += 1
else:
hi -= 1
return []Output for [2, 7, 11, 15], target=9:
[0, 1]Be ready to state these without hesitation: array scan O(n); nested pairs O(n²); hash map average O(1) lookup; sorting O(n log n); heap ops O(log n); balanced tree height O(log n), skewed O(n); graph BFS/DFS O(V+E). When you change approaches, update the complexity out loud.
Space matters on follow-ups: can you do it in O(1) extra space? Recursion depth counts. "The stack is O(n) for a skewed tree" is free signal.
Common mistakes
- Coding immediately. Wrong problem, missed constraints. Stop, clarify, restart.
- Optimal-or-bust. Zero code at minute 40. Ship brute force, then optimize.
- No dry-run. Off-by-ones survive until you walk the example.
Check yourself
- You have 8 minutes left and no optimal idea. What do you ship?
A correct brute force with complexity stated, then name the bottleneck if time remains.
- Why state brute force before you optimize?
It proves you understand the problem and gives a fallback if the clever path dies.
Key takeaways
- Follow clarify → examples → brute force → optimize → code → test → analyze every time.
- A correct slower solution beats silent perfectionism.
- Dry-run out loud and update complexity when the approach changes.
Further learning
Next: interview patterns.
Related
Coding interviews
Patterns, problem-solving process and communication for algorithm interviews — plus how practical coding rounds differ.
Interview patterns
Learn the trigger, not a code dump. Two pointers, windows, hashing, graphs and a few more cover most mediums.
Data structures in practice
Choosing data structures by memory layout, access pattern and the operations that matter, with the common ones for arrays, hash maps, heaps, trees, caches and graphs.