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 <= 100
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.
We read bits from the stream one by one, maintaining a window of the last len(pattern) bits. At each step, we check if the window matches the pattern. The first time it matches, we return the starting index.
classSolution {
public:int findPattern(InfiniteStream& stream, vector<int>& pattern) {
int n = pattern.size();
deque<int> window;
int idx =0;
while (true) {
int bit = stream.next();
window.push_back(bit);
if (window.size() > n) window.pop_front();
if (window.size() == n && vector<int>(window.begin(), window.end()) == pattern)
return idx - n +1;
idx++;
}
}
};
funcfindPattern(streamInfiniteStream, pattern []int) int {
n:= len(pattern)
window:= make([]int, 0, n)
idx:=0for {
bit:=stream.Next()
window = append(window, bit)
if len(window) > n {
window = window[1:]
}
if len(window) ==n {
match:=truefori:=0; i < n; i++ {
ifwindow[i] !=pattern[i] {
match = falsebreak }
}
ifmatch {
returnidx-n+1 }
}
idx++ }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
classSolution {
publicintfindPattern(InfiniteStream stream, int[] pattern) {
int n = pattern.length, idx = 0;
Deque<Integer> window =new ArrayDeque<>();
while (true) {
int bit = stream.next();
window.addLast(bit);
if (window.size() > n) window.pollFirst();
if (window.size() == n) {
int i = 0;
for (int b : window) {
if (b != pattern[i++]) break;
if (i == n) return idx - n + 1;
}
}
idx++;
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
classSolution {
funfindPattern(stream: InfiniteStream, pattern: IntArray): Int {
val n = pattern.size
val window = ArrayDeque<Int>()
var idx = 0while (true) {
val bit = stream.next()
window.addLast(bit)
if (window.size > n) window.removeFirst()
if (window.size == n && window.toIntArray().contentEquals(pattern))
return idx - n + 1 idx++ }
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
classSolution:
deffindPattern(self, stream: 'InfiniteStream', pattern: list[int]) -> int:
n = len(pattern)
window = []
idx =0whileTrue:
bit = stream.next()
window.append(bit)
if len(window) > n:
window.pop(0)
if len(window) == n and window == pattern:
return idx - n +1 idx +=1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
impl Solution {
pubfnfind_pattern(stream: &mut InfiniteStream, pattern: Vec<i32>) -> i32 {
let n = pattern.len();
letmut window = std::collections::VecDeque::new();
letmut idx =0;
loop {
let bit = stream.next();
window.push_back(bit);
if window.len() > n { window.pop_front(); }
if window.len() == n && window.iter().copied().eq(pattern.iter().copied()) {
return idx asi32- n asi32+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 (≤ 100), since we compare the window to the pattern at each step.
🧺 Space complexity: O(M), for the sliding window of pattern length.