I stopped brute-forcing LeetCode once I understood the difference in approach

Jamie5 Advanced 8/14/2026 232 views 0 likes 2 min read

I used to treat coding challenges like a guessing game. I vividly remember hitting a wall with the Longest Substring Without Repeating Characters problem. My initial instinct was a double-loop brute force approach, checking every possible substring. While it passed the easy test cases, the runtime exploded to $O(n^2)$ on larger inputs, making my laptop sound like a jet engine. My frustration stemmed not from a lack of Python knowledge, but from lacking a repeatable mental model to solve these problems efficiently.

Why describing the problem first matters

The breakthrough occurred when I stopped coding and started describing the problem in plain English: I simply needed to find the longest stretch of characters where no letter appeared twice. This was when the sliding window concept clicked. Instead of resetting my entire search every time I encountered a duplicate, I could just slide the left boundary of my window forward.

A five-step workflow for hard problems

I have since realized that most hard array or string problems can be solved using a consistent five-step workflow:

  1. Isolate the core constraint (e.g., what exactly makes a substring invalid?).
  2. Pick a state-tracking structure (usually a hash map or set for $O(1)$ lookups).
  3. Set up two pointers (a left and right boundary).
  4. Expand and shrink (move the right pointer to explore, and the left pointer to fix constraint violations).
  5. Track the global optimum (update your maximum or minimum result whenever the window is valid).

Brute force versus optimized performance

To demonstrate the performance difference, here is how the brute force approach fails compared to the optimized version.

The inefficient way (Brute Force $O(n^2)$):

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: # duplicate – stop this start position
                break
            seen.add(s[j])
            best = max(best, j - i + 1)
    return best

The issue here is that the inner loop restarts the seen set for every single index, repeating massive amounts of work. If you are dealing with a string of $10^5$ characters, this will crawl.

How the sliding window achieves linear time

The optimized way (Sliding Window $O(n)$):

def lengthOfLongestSubstring(s: str) -> int:
    """
    Sliding window with a hash map storing the most recent index of each character.
    """
    last_index = {} # char -> latest position
    left = 0 # start of the current window
    max_len = 0

    for right, ch in enumerate(s):
        # If ch was seen inside the current window, jump left just past its previous spot
        if ch in last_index and last_index[ch] >= left:
            left = last_index[ch] + 1

        # Update the most recent position of ch
        last_index[ch] = right

        # Window [left, right] is now valid
        max_len = max(max_len, right - left + 1)

    return max_len

This approach is a total victory because last_index allows us to jump the left pointer instantly. We never move backward, which guarantees linear time complexity. One huge gotcha: always remember the last_index[ch] >= left check. If you omit that, you might accidentally move your left pointer backward to a character that is already outside your current window, breaking the entire logic.

AI ProgrammingAI Codingproblemsolving

All Replies (3)

Want a live back-and-forth? Join the global AI chat room — login to talk.

C
CameronOwl Expert 8/14/2026

Finally clicked with sliding windows after months of struggle. How long did it take you to master them?

0 Reply
R
Riley2 Advanced 8/14/2026

Struggling with lookup speeds. Does a hash map actually beat a frequency array for these problems?

0 Reply
T
TaylorDreamer Intermediate 8/14/2026

Pattern mapping is a lifesaver. Which specific patterns actually helped you speed up your LeetCode time?

0 Reply

Write a Reply

Markdown supported