Medium
题目描述
对于一个整数流,实现一个数据结构来检查流中最后 k 个整数是否都等于 value。
实现 DataStream 类:
DataStream(int value, int k)用一个空的整数流和两个整数 value 和 k 初始化对象。boolean consec(int num)将 num 添加到整数流中。如果最后 k 个整数都等于 value,则返回 true,否则返回 false。如果少于 k 个整数,则条件不成立,返回 false。
示例 1:
输入
["DataStream", "consec", "consec", "consec", "consec"]
[[4, 3], [4], [4], [4], [3]]
输出
[null, false, false, true, false]
解释
DataStream dataStream = new DataStream(4, 3); //value = 4, k = 3
dataStream.consec(4); // 只解析了 1 个整数,所以返回 False。
dataStream.consec(4); // 只解析了 2 个整数。
// 由于 2 小于 k,返回 False。
dataStream.consec(4); // 解析的 3 个整数都等于 value,所以返回 True。
dataStream.consec(3); // 流中最后 k 个整数是 [4,4,3]。
// 由于 3 不等于 value,返回 False。
约束:
- 1 <= value, num <= 10^9
- 1 <= k <= 10^5
- 最多调用 consec 10^5 次
解题思路
这道题需要维护一个数据流,并检查最后 k 个元素是否都等于目标值。有两种主要的解题思路:
方法一:队列维护(直观但空间复杂度较高) 使用队列存储最后 k 个元素,每次添加新元素时维护队列大小为 k,然后检查队列中所有元素是否都等于目标值。
方法二:计数器优化(推荐) 关键观察:我们只需要知道最后 k 个元素中有多少个等于目标值。可以维护一个计数器,记录当前连续出现目标值的次数。当遇到非目标值时,计数器重置为 0;当遇到目标值时,计数器加 1(但不超过 k)。只有当计数器达到 k 时才返回 true。
这种方法避免了存储具体的元素,只需要 O(1) 的空间复杂度,同时每次操作也是 O(1) 时间复杂度。核心思想是:如果最后 k 个元素都等于目标值,那么必然是连续的 k 个目标值,所以只需要追踪连续计数即可。
代码实现
class DataStream {
private:
int targetValue;
int k;
int consecutiveCount;
public:
DataStream(int value, int k) : targetValue(value), k(k), consecutiveCount(0) {
}
bool consec(int num) {
if (num == targetValue) {
consecutiveCount++;
} else {
consecutiveCount = 0;
}
return consecutiveCount >= k;
}
};
class DataStream:
def __init__(self, value: int, k: int):
self.target_value = value
self.k = k
self.consecutive_count = 0
def consec(self, num: int) -> bool:
if num == self.target_value:
self.consecutive_count += 1
else:
self.consecutive_count = 0
return self.consecutive_count >= self.k
public class DataStream {
private int targetValue;
private int k;
private int consecutiveCount;
public DataStream(int value, int k) {
this.targetValue = value;
this.k = k;
this.consecutiveCount = 0;
}
public bool Consec(int num) {
if (num == targetValue) {
consecutiveCount++;
} else {
consecutiveCount = 0;
}
return consecutiveCount >= k;
}
}
var DataStream = function(value, k) {
this.value = value;
this.k = k;
this.count = 0;
};
DataStream.prototype.consec = function(num) {
if (num === this.value) {
this.count++;
} else {
this.count = 0;
}
return this.count >= this.k;
};
复杂度分析
| 操作 | 时间复杂度 | 空间复杂度 |
|---|---|---|
| DataStream() | O(1) | O(1) |
| consec() | O(1) | O(1) |
| 总体 | O(n) | O(1) |
其中 n 是 consec 方法的调用次数。
相关题目
- . Number of Zero-Filled Subarrays (Medium)