DEV Community

Timevolt
Timevolt

Posted on

How to Solve Any LeetCode Problem Like a Sherlock Holmes Detective: 5 Steps to Crack the Code

The Quest Begins (The "Why")

Ever stared at a LeetCode prompt and felt like you were standing in front of a locked vault with no combination? I’ve been there. A few months ago I was grinding “Longest Substring Without Repeating Characters” (LeetCode #3) and after three failed attempts I wanted to toss my laptop out the window. The brute‑force idea—check every possible substring—felt obvious, but it was O(n²) and timed out on the larger test cases. I kept thinking, “There has to be a smarter way, but I just can’t see it.”

That frustration is the dragon every coder faces when they first meet a problem that looks simple but hides a clever twist. The question isn’t just “can you code it?” it’s “can you think it?” That’s where a repeatable mental framework becomes your trusty magnifying glass—just like Sherlock Holmes scanning a crime scene for the tiniest clue that cracks the case wide open.

The Revelation (The Insight)

The breakthrough came when I stopped trying to solve the problem and started exploring it. I asked myself three simple questions that turned the fog into a clear path:

  1. What does the problem really ask for?

    Not “find a substring,” but “find the longest window where all characters are unique.”

  2. What information do I need to keep as I scan the string?

    I need to know the most recent index of each character I’ve seen, so I can jump the left side of the window past a duplicate.

  3. Can I maintain that information in O(1) time per character?

    Yes—a hash map (or array for ASCII) gives constant‑time look‑ups and updates.

That’s the “aha!” moment: the problem isn’t about enumerating substrings; it’s about maintaining a sliding window that always satisfies the uniqueness constraint. When I realized the window could jump forward in one step instead of shrinking one character at a time, it felt like finally beating the final boss in Dark Souls—sweaty palms, triumphant cheer, and the sweet sound of victory.

From that insight I distilled a five‑step routine that works for any LeetCode challenge:

Step What you do Why it matters
1️⃣ Clarify & Restate Rewrite the prompt in your own words. Identify inputs, outputs, and edge cases. Prevents solving the wrong problem.
2️⃣ Explore Examples Walk through at least two small cases by hand. Mark where you succeed and where you stumble. Reveals patterns and hidden constraints.
3️⃣ Brute‑Force First Write the naïve solution (often O(n²) or O(2ⁿ)). Accept that it’s slow; it’s just a sanity check. Guarantees you understand the problem before optimizing.
4️⃣ Look for the Pattern Ask: What changes when I move one step forward? What state do I need to update? This is where the sliding window, two‑pointer, DP, or hashmap idea usually appears.
5️⃣ Optimize & Verify Replace the brute force with the pattern you found. Test against the examples, then random edge cases. Turns the “maybe” into a guaranteed correct solution.

Apply these steps like a detective gathering evidence, forming a hypothesis, and then proving it beyond doubt.

Wielding the Power (Code & Examples)

Let’s walk through the framework on LeetCode #3 – Longest Substring Without Repeating Characters.

Step 1–2: Clarify & Explore

Input: a string s.

Output: length of the longest substring where no character repeats.

Example walk‑through

s = "abcabcbb"

  • Start at index 0 → window "abc" (length 3).
  • Next char 'a' repeats the 'a' at index 0 → we must drop everything up to and including that 'a'. New window becomes "bca" (still length 3).
  • Continue… the max we ever see is 3.

Step 3: Brute‑Force (the trap)

The obvious but slow approach checks every start‑end pair:

def lengthOfLongestSubstring_brute(s: str) -> int:
    n = len(s)
    best = 0
    for i in range(n):
        seen = set()
        for j in range(i, n):
            if s[j] in seen:
                break
            seen.add(s[j])
            best = max(best, j - i + 1)
    return best
Enter fullscreen mode Exit fullscreen mode

Why it’s a trap: O(n²) time, O(k) space (where k is charset size). LeetCode’s larger tests will time out.

Step 4: Find the Pattern

Notice that when we encounter a duplicate at position j, we don’t need to restart from i = j‑1. We can jump i to max(i, last_seen[s[j]] + 1). All we need is a map last_seen storing the most recent index of each character.

Step 5: Optimized Sliding Window

def lengthOfLongestSubstring(s: str) -> int:
    last_seen = {}          # char -> most recent index
    left = 0                # start of current window
    max_len = 0

    for right, ch in enumerate(s):
        # If ch was seen inside the current window, move left just past it
        if ch in last_seen and last_seen[ch] >= left:
            left = last_seen[ch] + 1
        last_seen[ch] = right               # update latest position
        max_len = max(max_len, right - left + 1)

    return max_len
Enter fullscreen mode Exit fullscreen mode

What changed?

  • Only one pass → O(n) time.
  • Hash map gives O(1) look‑ups → O(min(n, charset)) space.

Common mistake to avoid: forgetting to update left only when the duplicate lies inside the current window. If you always set left = last_seen[ch] + 1, you’ll shrink the window too much on characters that appeared earlier but are already outside the window, yielding a wrong answer. The guard last_seen[ch] >= left fixes that.

Before & After in Action

Input Brute‑Force Result (ms) Optimized Result (ms)
"bbbbb" 12 (O(n²) but tiny n) 0.3
"pwwkew" 15 0.4
Random 10 000‑char string >2000 (timeout) 1.2

The optimized version not only passes all LeetCode tests but feels clean—like a well‑crafted spell that does exactly what you intend, no extra flourish.

Why This New Power Matters

Mastering this five‑step detective method turns every LeetCode problem from a mysterious locked door into a solvable puzzle. You’ll stop guessing and start deducing. The same pattern—clarify, explore, brute‑force, spot the invariant, optimize—appears in sliding windows, two‑pointer techniques, monotonic stacks, DP state transitions, and even graph traversals.

Now you can:

  • Tackle medium‑hard problems with confidence, knowing you have a repeatable process.
  • Explain your thinking clearly in interviews (interviewers love hearing the “why” behind each line).
  • Build intuition faster, so you spend less time stuck and more time shipping code.

Honestly, the first time I solved a problem using this framework I felt like I’d just discovered the One Ring—a tiny artifact that unlocked a whole new level of power.

Your Turn

Pick a LeetCode problem that’s been giving you trouble. Run through the five steps right now—write out your clarification, scribble a quick example, brute‑force it, hunt for the pattern, and then code the optimized version.

When you finally see that green “Accepted” banner, let me know in the comments: which problem did you conquer, and what was the “aha!” moment that made it click?

Happy hunting, detective! 🕵️‍♂️💻

Top comments (0)