What Is Brute Force? The Coding Interview Approach Behind Every Optimal Solution

- Brute force is correct by construction: it checks every possibility and trades time for simplicity, making it the safest starting point
- State it first in coding interviews: naming the naive approach proves problem understanding before you optimize anything
- Input size is the signal: n ≤ 20 tolerates O(2^n); n = 1,000 needs better than O(n²); n = 10^6 needs O(n log n) at most
- The brute force reveals the redundancy that points directly to the right data structure or algorithm
- A correct slow solution beats a broken fast one: brute force is your fallback if the optimized version stalls mid-interview
- Narrating under pressure is a separate skill: knowing brute force and explaining it calmly while someone watches are two different things
You have a problem. You don't know where to start. Your instinct is to jump straight to the clever solution, but you have no idea what that is yet.
The right move is almost always: try everything.
That's brute force. Generate every possible answer and check which ones are correct. No tricks, no optimization, no insight required. Just exhaustive enumeration. In a coding interview, it's a more powerful starting point than most engineers realize. And yet everyone treats it like they're confessing to a crime.
Always Right, Often Slow
Brute force is correct by construction. Check every possibility and you will find the right answer. The only question is whether you can afford the time.
Take Two Sum: given an array of numbers and a target, find two numbers that add up to the target.
The brute force writes itself. Check every pair.
def two_sum(nums, target): n = len(nums) for i in range(n): for j in range(i + 1, n): if nums[i] + nums[j] == target: return [i, j]
O(n²). For a million elements, you'd be waiting long enough to make a coffee, drink the coffee, and question your career. But this code is obviously correct. No edge cases to reason about, no clever invariant to maintain. You can look at it and immediately see why it works. You spend time to save thinking. That trade is the entire point of brute force.
What Brute Force Actually Looks Like
Brute force takes a few common shapes.
Nested loops. The most common version. Two nested loops give you every pair at O(n²). Three loops give every triplet at O(n³). If you're checking all combinations of elements from an array, you're doing brute force.
Generating all subsets. For n elements there are 2^n subsets. This shows up in problems like "find the subset that sums to k" before you know dynamic programming exists.
def subset_sum_exists(nums, target): n = len(nums) for mask in range(1 << n): # 2^n possibilities total = sum(nums[i] for i in range(n) if mask & (1 << i)) if total == target: return True return False
Generating all permutations. If order matters, try every ordering. For n elements that's n! possibilities. Twenty elements gives you a number larger than the count of atoms in the observable universe. Your laptop will not finish this. The universe might not finish this.
Naive string search. The simplest pattern-matching algorithm slides a pattern across the text one character at a time, checking at each position. O(n * m). KMP and Rabin-Karp both cut this down, but the naive version is correct and easy to reason about.
Recursive enumeration without memoization. Classic Fibonacci recomputes the same subproblems over and over, turning O(n) work into O(2^n). The brute force isn't wrong. It's just enthusiastically redundant.
The unifying theme: brute force never skips anything. It's the solution you'd write if you had infinite time, infinite electricity, and didn't care about either.
Why You State Brute Force First in Coding Interviews
Most guides treat brute force as something to apologize for. Don't.
Stating your brute force solution first is expected behavior at any level. It proves you understand the problem before you optimize anything. And it cures blank-page paralysis. Starting with brute force gives you something to write, something to reason about, and often a direct pointer toward the optimized solution. The blank page is your enemy. Write anything true and you've already won half the battle.
If you go silent hunting for the clever answer, your interviewer has nothing to engage with. "The naive approach is O(n²) with nested loops, which breaks down for large inputs, so let me think about what we can exploit" lets the interviewer confirm you're on track or nudge you toward something better. That conversation is what interviews are built to produce.
The brute force is also your fallback. If you run out of time on the optimized version, you have working code. A correct O(n²) solution beats a broken O(n log n) attempt every single time. Interviewers can evaluate a correct slow solution. They cannot evaluate an incorrect fast one, because there is nothing to evaluate.
For how this fits into the full interview sequence, how to approach coding interview problems covers reading constraints through submitting working code.
Input Size Tells You How Much to Optimize
Brute force approaches follow predictable complexity patterns. Learning to recognize them tells you how far you need to go.
| Brute Force Pattern | Time Complexity | Common Context |
|---|---|---|
| Check every pair | O(n²) | Two Sum, 3Sum setup |
| Check every triplet | O(n³) | 3Sum naive |
| Generate all subsets | O(2^n) | Subset sum, combinations |
| Generate all permutations | O(n!) | Traveling salesman, anagram check |
| Naive string match | O(n * m) | Pattern in text |
| Recursive Fibonacci | O(2^n) | DP without memo |
Input size is the signal. If n is around 10 to 20, O(2^n) might be acceptable. If n is 1,000, you need better than O(n²). If n is 10^6, you need O(n log n) at most. Interviewers expect you to cite this without prompting. It sounds like magic when you do it. It's just pattern matching.
The big-O notation guide covers how to read any loop or recursion and derive its complexity from first principles.
The Brute Force Points to the Optimization
When you write the brute force, you see what's redundant. That's where the optimization lives.
Back to Two Sum. The nested loop checks every pair. At index i, you're asking: is there a j where nums[j] equals target minus nums[i]? The inner loop is you searching for that j. A hash map answers that question in O(1). Replace the inner loop with a lookup, and the solution drops to O(n).
def two_sum_optimized(nums, target): seen = {} for i, num in enumerate(nums): complement = target - num if complement in seen: return [seen[complement], i] seen[num] = i
The optimization became obvious once you could name what the brute force was doing. The repeated inner search became a hash map lookup. You couldn't have seen that without writing the slow version first.
Sorting to avoid nested search. Prefix sums to avoid repeated range queries. Memoization to avoid recomputing overlapping subproblems. In every case, the opportunity is visible once you've written the brute force and asked: what is this doing over and over? If you jump straight to "I need a hash map," you're skipping the reasoning that makes the answer stick. Next problem, you're stuck again.
Five coding interview problems where your first solution isn't optimal walks through this pipeline on problems where the brute-to-optimal gap is most instructive.
The Sequence That Works
Most interviews want to see this order, whether you're walking through it explicitly or not.
- Restate the problem. Confirm what you're solving before you write anything.
- State the brute force. Name the approach and the complexity. You don't always need to code it.
- Name the waste. What is the brute force doing repeatedly that it doesn't need to?
- Optimize. What data structure or algorithm eliminates that repetition?
- Code the optimized version.
You can skip coding the brute force if it's clearly understood. "We could check every pair in O(n²), but a hash map gets this down to O(n)" is enough to demonstrate the thinking. For harder problems, writing the brute force first often shakes loose the right idea. It's not a waste of time. It's reconnaissance.
How to solve LeetCode mediums makes the same argument: brute force plus one insight is the reliable path, not jumping to an optimal approach you haven't earned yet.
Where You'll See It
Graphs. Visiting every vertex and edge from every vertex is O(V * (V + E)). BFS and DFS cut this to O(V + E) by tracking visited nodes and never revisiting.
Strings. Comparing every pair of substrings for longest common substring is O(n² * m). Dynamic programming brings it to O(n * m) by caching the overlapping comparisons the brute force repeats.
Sorting. Selection sort and bubble sort compare every pair: O(n²). Merge sort exploits the structure of partially sorted data for O(n log n). The brute force makes the problem structure obvious, then you throw it away.
Dynamic programming. Almost every DP problem has an exponential brute force that recomputes overlapping subproblems. Memoization caches those results and turns exponential into polynomial. You need the recursion first. You can't add the cache if you haven't written the recursion. This is not optional. It's the sequence.
Performing It Under Pressure
Knowing when to use brute force is one skill. Saying it out loud while a stranger watches you type is another.
In a real interview, you have to state the approach, its complexity, and your reasoning for moving past it, all at once, while your nervous system is doing something unhelpful. You've solved this problem a hundred times alone. The interviewer opens a tab and suddenly you can't remember what a loop is. That gap between solo competence and live performance is the actual thing practice is supposed to close.
That narration is what breaks down under pressure, not your knowledge. SpaceComplexity runs voice-based mock interviews with rubric-based feedback across exactly these dimensions: whether you stated the brute force, named its complexity, articulated why it's insufficient before jumping to the optimization. It's the gap between knowing the concept and performing it live that repetition closes.
Further Reading
- Brute-force search: Wikipedia's overview of exhaustive search across domains
- Time complexity: formal definitions and the complexity classes behind the patterns above
- Big-O Cheat Sheet: quick reference for common algorithm and data structure complexities
- Introduction to Algorithms (CLRS): the standard textbook; Chapter 2 covers loop-based analysis, later chapters show the brute force to optimal transition across sorting, graphs, and DP