Find Pattern in Infinite Stream I
MediumUpdated: Aug 2, 2025
Practice on:
Problem
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 either0or1) 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, ...].
Examples
Example 1:
Input: stream = [1,1,1,0,1,1,1,...], pattern = [0,1]
Output: 3
Explanation: 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:
Input: stream = [0,0,0,0,...], pattern = [0]
Output: 0
Explanation: The first occurrence of the pattern [0] is highlighted in the stream [**_0_** ,...], which starts at index 0.
Example 3:
Input: stream = [1,0,1,1,0,1,1,0,1,...], pattern = [1,1,0,1]
Output: 2
Explanation: 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 <= 100patternconsists only of0and1.streamconsists only of0and1.- The input is generated such that the pattern's start index exists in the first
105bits of the stream.
Solution
Method 1 – Sliding Window (Brute Force)
Intuition
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.
Approach
- Initialize an empty list or queue to store the last
len(pattern)bits. - For each bit read from the stream:
- Add the bit to the window.
- If the window size exceeds the pattern length, remove the oldest bit.
- If the window matches the pattern, return the current index minus pattern length + 1.
- Continue until a match is found.
Code
C++
class Solution {
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++;
}
}
};
Go
func findPattern(stream InfiniteStream, pattern []int) int {
n := len(pattern)
window := make([]int, 0, n)
idx := 0
for {
bit := stream.Next()
window = append(window, bit)
if len(window) > n {
window = window[1:]
}
if len(window) == n {
match := true
for i := 0; i < n; i++ {
if window[i] != pattern[i] {
match = false
break
}
}
if match {
return idx - n + 1
}
}
idx++
}
}
Java
class Solution {
public int findPattern(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++;
}
}
}
Kotlin
class Solution {
fun findPattern(stream: InfiniteStream, pattern: IntArray): Int {
val n = pattern.size
val window = ArrayDeque<Int>()
var idx = 0
while (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++
}
}
}
Python
class Solution:
def findPattern(self, stream: 'InfiniteStream', pattern: list[int]) -> int:
n = len(pattern)
window = []
idx = 0
while True:
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
Rust
impl Solution {
pub fn find_pattern(stream: &mut InfiniteStream, pattern: Vec<i32>) -> i32 {
let n = pattern.len();
let mut window = std::collections::VecDeque::new();
let mut 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 as i32 - n as i32 + 1;
}
idx += 1;
}
}
}
TypeScript
class Solution {
findPattern(stream: InfiniteStream, pattern: number[]): number {
const n = pattern.length;
const window: number[] = [];
let idx = 0;
while (true) {
const bit = stream.next();
window.push(bit);
if (window.length > n) window.shift();
if (window.length === n && window.every((v, i) => v === pattern[i]))
return idx - n + 1;
idx++;
}
}
}
Complexity
- ⏰ Time complexity:
O(N * M), whereNis the index of the first match (at most 1e5), andMis 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.