When youโre given a long binary string like 00110110, the problem LeetCode 1461 โ Check If a String Contains All Binary Codes of Size K asks something very specific:
Does this string contain every possible binary substring of length
k?
At first glance, it sounds like youโd have to generate all 2^k binary codes and search for each oneโwhich would be slow. The good news is: you donโt need to generate anything. You can solve it efficiently by scanning the string once.
Problem overview
You are given:
- a binary string
s(only'0'and'1') - an integer
k
Return True if every binary code of length k appears somewhere in s as a substring, otherwise return False.
Example
If k = 2, the required codes are:
00,01,10,11โ total2^2 = 4
If the string contains all of them at least once, the answer is True.
Key idea (the important observation)
There are exactly:
2^kdifferent binary codes of lengthk
And the string s can produce at most:
n - k + 1substrings of lengthk(wheren = len(s))
So if:
n - k + 1 < 2^k
โฆitโs impossible for s to contain all binary codes. We can return False immediately.
This simple check saves time on many inputs.
Best approach: Sliding window + bitmask (rolling binary value)
Instead of slicing substrings like s[i:i+k] repeatedly (which costs extra time and memory), we treat each window of length k as a number.
How we โrollโ the window
As we move from left to right:
- Shift the current value left by 1 (like multiplying by 2)
- Add the new bit (
0or1) - Keep only the last
kbits using a mask
That mask is:
mask = (1 << k) - 1
So the rolling update becomes:
cur = ((cur << 1) & mask) | bit
Once weโve processed at least k characters, cur represents the current length-k substring as an integer from 0 to 2^k - 1.
We track which values have appeared. If weโve seen all 2^k values, return True.
Correct and optimized Python solution
This version is fast, clear, and avoids confusing boolean-to-int behavior by converting bits explicitly.
class Solution:
def hasAllCodes(self, s: str, k: int) -> bool:
n = len(s)
need = 1 << k # total codes = 2^k
# Early exit: not enough windows to cover all codes
if n < k or (n - k + 1) < need:
return False
seen = [False] * need
mask = need - 1
cur = 0
found = 0
for i, ch in enumerate(s):
bit = 1 if ch == '1' else 0
cur = ((cur << 1) & mask) | bit
# Start checking once window size is k
if i >= k - 1:
if not seen[cur]:
seen[cur] = True
found += 1
if found == need:
return True
return False
Step-by-step example (quick walkthrough)
Let:
s = "00110110"k = 2need = 4(00, 01, 10, 11)
As we slide a window of size 2, we encounter:
00โ01โ11โ10โ
We found all 4 codes โ return True.
Why this solution is efficient
Time complexity
- O(n) โ one pass through the string
Space complexity
- O(2^k) โ to store which binary codes weโve seen
This is the standard optimal approach for LeetCode 1461.
Common mistakes to avoid
- Building every substring with slicing (
s[i:i+k]) inside a loop โ slower for large inputs. - Not using a mask โ without
& mask, your rolling number keeps growing and stops representing only the lastkbits. - Skipping the early exit check โ wastes time on impossible cases.