comments | difficulty | edit_url | tags | |||||
---|---|---|---|---|---|---|---|---|
true |
中等 |
|
给定一个二进制数组 pattern
和一个类 InfiniteStream
的对象 stream
表示一个下标从 0 开始的二进制位无限流。
类 InfiniteStream
包含下列函数:
int next()
:从流中读取 一个 二进制位 (是0
或1
)并返回。
返回 第一个使得模式匹配流中读取的二进制位的 开始下标。例如,如果模式是 [1, 0]
,第一个匹配是流中的高亮部分 [0, 1, 0, 1, ...]
。
示例 1:
输入: stream = [1,1,1,0,1,1,1,...], pattern = [0,1] 输出: 3 解释: 模式 [0,1] 的第一次出现在流中高亮 [1,1,1,0,1,...],从下标 3 开始。
示例 2:
输入: stream = [0,0,0,0,...], pattern = [0] 输出: 0 解释: 模式 [0] 的第一次出现在流中高亮 [0,...],从下标 0 开始。
示例 3:
输入: stream = [1,0,1,1,0,1,1,0,1,...], pattern = [1,1,0,1] 输出: 2 解释: 模式 [1,1,0,1] 的第一次出现在流中高亮 [1,0,1,1,0,1,...],从下标 2 开始。
提示:
1 <= pattern.length <= 100
pattern
只包含0
或1
。stream
只包含0
或1
。- 生成的输入使模式的开始下标在流的前
105
个二进制位中。
我们注意到,数组
接下来,我们遍历数据流,同样维护两个
时间复杂度
# Definition for an infinite stream.
# class InfiniteStream:
# def next(self) -> int:
# pass
class Solution:
def findPattern(
self, stream: Optional["InfiniteStream"], pattern: List[int]
) -> int:
a = b = 0
m = len(pattern)
half = m >> 1
mask1 = (1 << half) - 1
mask2 = (1 << (m - half)) - 1
for i in range(half):
a |= pattern[i] << (half - 1 - i)
for i in range(half, m):
b |= pattern[i] << (m - 1 - i)
x = y = 0
for i in count(1):
v = stream.next()
y = y << 1 | v
v = y >> (m - half) & 1
y &= mask2
x = x << 1 | v
x &= mask1
if i >= m and a == x and b == y:
return i - m
/**
* Definition for an infinite stream.
* class InfiniteStream {
* public InfiniteStream(int[] bits);
* public int next();
* }
*/
class Solution {
public int findPattern(InfiniteStream infiniteStream, int[] pattern) {
long a = 0, b = 0;
int m = pattern.length;
int half = m >> 1;
long mask1 = (1L << half) - 1;
long mask2 = (1L << (m - half)) - 1;
for (int i = 0; i < half; ++i) {
a |= (long) pattern[i] << (half - 1 - i);
}
for (int i = half; i < m; ++i) {
b |= (long) pattern[i] << (m - 1 - i);
}
long x = 0, y = 0;
for (int i = 1;; ++i) {
int v = infiniteStream.next();
y = y << 1 | v;
v = (int) ((y >> (m - half)) & 1);
y &= mask2;
x = x << 1 | v;
x &= mask1;
if (i >= m && a == x && b == y) {
return i - m;
}
}
}
}
/**
* Definition for an infinite stream.
* class InfiniteStream {
* public:
* InfiniteStream(vector<int> bits);
* int next();
* };
*/
class Solution {
public:
int findPattern(InfiniteStream* stream, vector<int>& pattern) {
long long a = 0, b = 0;
int m = pattern.size();
int half = m >> 1;
long long mask1 = (1LL << half) - 1;
long long mask2 = (1LL << (m - half)) - 1;
for (int i = 0; i < half; ++i) {
a |= (long long) pattern[i] << (half - 1 - i);
}
for (int i = half; i < m; ++i) {
b |= (long long) pattern[i] << (m - 1 - i);
}
long x = 0, y = 0;
for (int i = 1;; ++i) {
int v = stream->next();
y = y << 1 | v;
v = (int) ((y >> (m - half)) & 1);
y &= mask2;
x = x << 1 | v;
x &= mask1;
if (i >= m && a == x && b == y) {
return i - m;
}
}
}
};
/**
* Definition for an infinite stream.
* type InfiniteStream interface {
* Next() int
* }
*/
func findPattern(stream InfiniteStream, pattern []int) int {
a, b := 0, 0
m := len(pattern)
half := m >> 1
mask1 := (1 << half) - 1
mask2 := (1 << (m - half)) - 1
for i := 0; i < half; i++ {
a |= pattern[i] << (half - 1 - i)
}
for i := half; i < m; i++ {
b |= pattern[i] << (m - 1 - i)
}
x, y := 0, 0
for i := 1; ; i++ {
v := stream.Next()
y = y<<1 | v
v = (y >> (m - half)) & 1
y &= mask2
x = x<<1 | v
x &= mask1
if i >= m && a == x && b == y {
return i - m
}
}
}