2025, Sep 17 09:00

Longest Substring Without Repeating Characters in Python: Sliding Window Fixes, Pitfalls, and a Working Example

Learn how to fix None output and implement a sliding window to find the longest substring without repeating characters in Python. Pitfalls and a clean example.

When you implement a sliding window to find the length of the longest substring without repeating characters, a common symptom of a broken solution is seeing None in the terminal instead of a number. This usually points to a missing return and a couple of typical sliding window pitfalls. Below is a concise walkthrough of what goes wrong and how to wire the logic correctly.

Working example

The following version uses a dynamic set, two pointers, and returns the computed length. It preserves the sliding window behavior end to end.

def longest_unique_span(text):
    seen_chars = set()
    best_len = 0
    left = 0

    for right in range(len(text)):
        while text[right] in seen_chars:
            seen_chars.remove(text[left])
            left += 1
        seen_chars.add(text[right])
        best_len = max(best_len, right - left + 1)

    return best_len


if __name__ == "__main__":
    sample = "abcabcbb"
    print(longest_unique_span(sample))  
    # output: 3

What went wrong and why it happens

Seeing None printed means the function finishes without returning a value. In Python, a function with no explicit return produces None by default, which is exactly what ends up in the terminal. Fixing that requires returning the computed length at the end.

Another issue is initializing the set with all characters ahead of time. The sliding window approach relies on growing and shrinking the window dynamically as you iterate, so the set must start empty and be updated on the fly.

Finally, adding indices to the set instead of characters breaks the entire duplicate detection logic. You need to track the actual elements of the window, so each step should add the character at the current position, not the position itself.

The fix

The solution uses two pointers that define the window bounds. The right pointer advances through the string. If the current character is already inside the window, the left pointer moves forward, removing characters from the set until the duplicate is eliminated. Then the current character is added, and the maximum length is updated with the current window size. At the end the function returns the computed maximum length, which resolves the None output and yields the expected result.

Why this matters

Getting the mechanics of the sliding window right is critical for correctness. Returning the result avoids None in the output, maintaining a dynamic set ensures the window reflects the current substring, and working with characters instead of indices makes duplicate checks accurate.

Takeaways

Always return the computed value from the function so the terminal shows the expected number. Build the window state dynamically rather than preloading it. Track characters, not indices, inside the set. And keep the two-pointer flow tight: expand with the right pointer, shrink from the left when a duplicate appears, update the maximum length, repeat. With these pieces in place, the algorithm consistently finds the length of the longest substring without repeating characters.

The article is based on a question from StackOverflow by Jared McCarthy and an answer by Ajeet Verma.