Problem Description
Given an infinite binary stream (accessed via a next() call) and a binary pattern, return the first starting index where the pattern is found in the stream.
Key Insights
- Use a sliding window of size equal to the pattern’s length.
- Calculate a rolling hash for the current window to quickly check for potential matches.
- Compare the computed rolling hash against the precomputed hash of the pattern.
- When the hashes match, perform an element-wise verification to avoid false positives due to hash collisions.
- The algorithm terminates once the pattern is found within the first 10^5 bits of the stream.
Space and Time Complexity
Time Complexity: O(n) in the worst case, where n is the number of bits read until a match is found (bounded by 10^5).
Space Complexity: O(m), where m is the length of the pattern.
Solution
The solution leverages a rolling hash with a sliding window.
- Precompute the hash for the pattern using a chosen base (2, since data is binary) and a large prime modulus. Also compute base^(m-1) modulo the modulus to help in removing the leftmost digit’s contribution from the rolling hash.
- As bits are read from the stream one-by-one, maintain a rolling window of the last m bits and its corresponding hash.
- Once the window has m bits, compare the rolling hash with the pattern’s hash. If they match, compare the bits in the current window with the pattern for confirmation.
- Slide the window by removing the oldest bit and adding the new bit; update the rolling hash accordingly.
- Return the starting index of the window as soon as the pattern is confirmed.