You are given a binary array pattern and an object stream of class
InfiniteStream representing a 0-indexed infinite stream of bits.
The class InfiniteStream contains the following function:
int next(): Reads a single bit (which is either 0 or 1) from the stream and returns it.
Return thefirst starting index where the pattern matches the bits read from the stream. For example, if the pattern is [1, 0], the first match is the highlighted part in the stream [0, **_1, 0_** , 1, ...].
Input: stream =[1,1,1,0,1,1,1,...], pattern =[0,1]Output: 3Explanation: The first occurrence of the pattern [0,1]is highlighted in the stream [1,1,1,**_0,1_**,...], which starts at index 3.
Example 2:
1
2
3
Input: stream =[0,0,0,0,...], pattern =[0]Output: 0Explanation: The first occurrence of the pattern [0]is highlighted in the stream [**_0_**,...], which starts at index 0.
Example 3:
1
2
3
Input: stream =[1,0,1,1,0,1,1,0,1,...], pattern =[1,1,0,1]Output: 2Explanation: The first occurrence of the pattern [1,1,0,1]is highlighted in the stream [1,0,**_1,1,0,1_**,...], which starts at index 2.
Constraints:
1 <= pattern.length <= 10^4
pattern consists only of 0 and 1.
stream consists only of 0 and 1.
The input is generated such that the pattern’s start index exists in the first 105 bits of the stream.
KMP preprocesses the pattern to build a “failure function” (lps array) that allows us to skip unnecessary comparisons. As we read the stream, we track how much of the pattern matches so far, and efficiently reset when a mismatch occurs.
classSolution {
public:int findPattern(InfiniteStream& stream, vector<int>& pattern) {
int n = pattern.size();
vector<int> lps(n, 0);
for (int i =1, len =0; i < n; ) {
if (pattern[i] == pattern[len]) lps[i++] =++len;
elseif (len) len = lps[len-1];
else lps[i++] =0;
}
int j =0, idx =0;
while (true) {
int bit = stream.next();
while (j >0&& bit != pattern[j]) j = lps[j-1];
if (bit == pattern[j]) j++;
if (j == n) return idx - n +1;
idx++;
}
}
};
classSolution:
deffindPattern(self, stream: 'InfiniteStream', pattern: list[int]) -> int:
n = len(pattern)
lps = [0] * n
l =0for i in range(1, n):
while l >0and pattern[i] != pattern[l]:
l = lps[l-1]
if pattern[i] == pattern[l]:
l +=1 lps[i] = l
j =0 idx =0whileTrue:
bit = stream.next()
while j >0and bit != pattern[j]:
j = lps[j-1]
if bit == pattern[j]:
j +=1if j == n:
return idx - n +1 idx +=1
⏰ Time complexity: O(N + M), where N is the index of the first match (at most 1e5), and M is the pattern length (≤ 10^4), due to KMP preprocessing and matching.
🧺 Space complexity: O(M), for the lps array and pattern window.