How to Solve LeetCode Mediums: Brute Force Plus One Idea

May 25, 20268 min read
interview-prepdsaleetcodealgorithms
How to Solve LeetCode Mediums: Brute Force Plus One Idea
TL;DR
  • Brute force first: it diagnoses exactly where your solution wastes work, not as a warm-up ritual but as a targeting tool
  • Hashing converts any O(n) repeated lookup inside a loop into O(1) with a single hash map or set
  • Sorting unlocks structure when arbitrary order makes the answer hard; pay O(n log n) once, then layer on two pointers
  • Two pointers replace the inner loop when two quantities move in opposite directions on a sorted input
  • Sliding window handles contiguous subarray constraints that degrade monotonically as the window grows
  • Read the constraints: n up to 10^5 rules out O(n²), pointing directly at which optimization family applies
  • The debrief habit ("brute force was X, bottleneck was Y, fix was Z") builds pattern recognition faster than raw volume

LeetCode mediums feel random until they don't. Then you realize almost all of them follow the same skeleton: write the obvious O(n²) solution, spot the bottleneck, and apply one optimization from a surprisingly short list. The randomness was never in the problem. It was in not knowing the list.

Cover: knight labeled "10 years of software engineering experience" getting stabbed by "leetcode medium after 10 years of no leetcode"

The Brute Force Is Not a Failure

Here's the trap most people fall into: they stare at a medium for four minutes, feel nothing happening in their brain, and conclude they're not smart enough. Then they look at the solution and think "oh obviously." This happens every time, and yet every time it feels like a personal failing.

It isn't. You're skipping the diagnostic.

Write the brute force first. Not as a warmup ritual. As a way to see where the problem is bleeding time.

Take Two Sum. Two nested loops, O(n²). The waste is obvious once you look: for every element, you scan the entire array just to find its complement. You're doing O(n) work to answer a question that should take O(1). Now the problem is concrete. How do you find a complement in O(1) instead of O(n)? Hash map. Done.

The brute force didn't slow you down. It handed you a roadmap.

This is also the answer to "I get stuck and don't know where to start." You always know where to start. Start with the worst possible solution that would technically work. Then ask: what part of this is embarrassingly slow? The answer to that question is almost always one of four things.

Code snippet showing a while loop that brute-forces computing n² by incrementing k until k equals n*n, with comments saying "I don't know what I did but it works / Please don't modify it"

When you write the brute force and somehow convince yourself it's correct.

The Four Families That Solve Most LeetCode Mediums

Nearly every medium optimization falls into one of four categories. Knowing which signal triggers which family is most of the skill. Once you have this map, "medium problems feel random" becomes "medium problems wear costumes."

Hashing: "Have I Seen This Before?"

The signal is repeated lookup. You're searching for something, counting something, or checking existence inside a loop. Every time you think "I need to know if X exists in something I've already processed," that's a hash map or hash set waiting to happen.

Two Sum, Subarray Sum Equals K, Group Anagrams, Longest Consecutive Sequence. They look wildly different. All of them collapse to: compute something, store it in a hash structure, look it up later in O(1). The hash map is the single most useful tool in the medium toolkit, and recognizing when to reach for it is probably worth 20% of your interview performance alone.

The tell is always the same. You're inside a loop. You need to look something up. If you reach for another loop, you've missed it.

A close relative of hashing is the prefix sum. When a problem asks about subarrays with a target sum, the standard move is to track cumulative sums in a hash map so you can ask "have I seen a prefix that, subtracted from here, gives the target?" Subarray Sum Equals K is the canonical version. The brute force is O(n²). The hash map version is O(n). Same family, slightly different costume.

Sorting: "Order Would Make This Obvious"

The signal is a problem that seems hard because elements arrive in arbitrary order, but sorted the answer would fall out immediately. Ask: does rearranging the input help? If yes, sort first.

3Sum is the clearest example. Three nested loops is O(n³). Sort the array, fix one element, run two pointers on the rest. The sort costs O(n log n) but buys you all the structure you need. You went from a brute force that times out on n=3000 to one that passes with room to spare.

The trap here is forgetting that sorting is available. You look at an unordered array and try to build something clever. Then you see the editorial and it says "first, sort the array" and you throw your laptop. The sort is the move. It's okay.

Two Pointers: "Two Quantities Move in Opposite Directions"

The signal is a sorted array with a constraint that lets you eliminate candidates from the ends. When moving one pointer inward is guaranteed to make one quantity go up and the other go down, two pointers replace the inner loop entirely.

Container With Most Water: the area is width times the shorter height. Wider is always better. So you shrink from whichever side is shorter, because keeping the shorter side can only make things worse. One pass, O(n).

The invariant is the key. You need to convince yourself that moving a pointer definitely rules out some cases. If you can't articulate why moving left inward is safe, you haven't found the invariant yet.

Sliding Window: "I Need Something About a Contiguous Subarray"

The signal is the word "subarray" or "substring" combined with a constraint you can track incrementally. Add an element on the right, remove one from the left when the constraint breaks. If adding more elements only makes the constraint harder to satisfy, a window works.

Longest Substring Without Repeating Characters, Minimum Window Substring, Maximum Average Subarray of Size K. Once you see the shape, the code almost writes itself. There are two flavors: fixed-size windows (the window size k is given) and variable-size windows (shrink from the left when you violate the constraint). Most of the interesting ones are variable-size.

The sliding window is worth drilling until reaching for it is automatic. It shows up constantly and the implementation is always the same five-line loop.

The Constraints Are Telling You the Answer

This is the part most people skip, and it explains a lot of medium struggles.

The constraints telegraph which family to use. Before you write anything, look at n.

If n is up to 10^5, you need O(n) or O(n log n). That rules out nested loops, which points toward hashing or a sorted structure. If the input is already sorted, two pointers are immediately on the table. If the problem asks about contiguous subarrays with a condition that degrades as the window grows, you're looking at a sliding window. If n is tiny, say up to 20, the problem is probably asking for an exponential solution and you're looking at backtracking or bitmask DP.

The constraint also tells you when the "obvious" approach is fine. n up to 1000? O(n²) passes. n up to 100? O(n³) is probably acceptable. These are not trick questions. The constraint is the problem setter's way of pointing at the intended solution without just telling you what it is.

There's also a subtler signal: the presence or absence of sorted input. If the problem gives you a sorted array, two pointers are almost certainly in play. If it doesn't and the brute force is too slow, your first question should be "what if I sort first?" Sorting costs O(n log n), which fits under most O(n log n) budgets, and it unlocks two pointers and binary search. Most problems that feel like they need something exotic actually just need a sort.

The optimization isn't a creative leap. It's a pattern match. The constraints imply a complexity budget. The budget rules out certain families. The remaining families narrow down the mechanics. What feels like an insight is usually just the right table lookup.

This is why mediums feel random early on. You're trying to jump to the solution without running the diagnostic. Brute force first, identify the bottleneck, match it to a family. The insight is almost always one of these four moves wearing problem-specific clothing.

Stoic cat sitting professionally at a table with the text "When you're 30 minutes into the interview and the candidate is still coding their fizzbuzz solution but you have to stay professional"

The interviewer watching you explain the O(n²) brute force with four minutes left on the clock.

One Habit That Actually Builds This Skill

When you finish a medium, write one sentence before closing the tab: "The brute force was X, the bottleneck was Y, the fix was Z."

Over 30 or 40 problems you'll see the same four fixes show up in different costumes. Group Anagrams looks nothing like Subarray Sum Equals K. But they're both "compute something, store it, look it up." Two Sum looks nothing like Longest Consecutive Sequence. Also both hash map problems. The costume changes. The move doesn't.

That debrief is what separates people who actually improve from people who just grind. Volume gives you exposure. The debrief gives you recognition. Those are different skills and only one of them transfers to a real interview.

Recognition under pressure, when someone's watching, the clock is running, and your brain is producing a sound like a dial-up modem, is a different skill than recognition at home with unlimited time. SpaceComplexity puts you in that condition so the pattern matching becomes reflex before it needs to be.

The medium isn't hard. You just didn't know the list yet.