LeetCode 933: Recent Counter — 使用 Java 实现
在这篇博客中,我们将讨论 LeetCode 第 933 题——Recent Counter。题目要求我们设计一个 RecentCounter
类,能够记录请求的时间戳,并返回在给定时间窗口内的请求数量。
问题描述
题目:设计一个 RecentCounter
类,支持以下操作:
- ping(int t): 记录一个新的请求时间戳
t
,并返回在时间窗口[t - 3000, t]
内的请求数量。
输入输出示例
输入:
["RecentCounter", "ping", "ping", "ping", "ping"]
[[null], [1], [100], [3001], [3002]]
输出:
[null, 1, 2, 3, 3]
说明
RecentCounter
是一个类的实例化对象。- 第一次调用
ping(1)
,返回 1,因为只有一个请求在时间窗口内。 - 第二次调用
ping(100)
,返回 2,因为时间窗口内有两个请求(1 和 100)。 - 第三次调用
ping(3001)
,返回 3,因为时间窗口内有三个请求(1、100 和 3001)。 - 第四次调用
ping(3002)
,返回 3,因为时间窗口内仍然只有三个请求。
解决方案
为了有效地管理请求时间戳,我们可以使用 Java 的 Queue
接口及其 LinkedList
实现。队列是一种先进先出(FIFO)的数据结构,非常适合处理时间戳。
代码实现
以下是 RecentCounter
类的完整代码实现:
import java.util.LinkedList;
import java.util.Queue;
class RecentCounter {
private Queue<Integer> queue;
public RecentCounter() {
//构造函数用于初始化队列
queue = new LinkedList<Integer>();
}
public int ping(int t) {
// 添加当前时间戳到队列
queue.add(t);
// 移除不在时间窗口内的请求
while (!queue.isEmpty() && t - queue.peek() > 3000) {
queue.poll();
}
// 返回当前时间窗口内的请求数量
return queue.size();
}
}
代码解析
-
成员变量:
Queue<Integer> queue
: 用于存储请求的时间戳。
-
构造函数:
- 初始化
queue
为一个新的LinkedList
实例。
- 初始化
-
ping 方法:
- 将当前时间戳
t
添加到队列。 - 使用循环检查队列的头部元素,如果它不在时间窗口
[t - 3000, t]
内,就将其移除。 - 返回队列的大小,即在该时间窗口内的请求数量。
- 将当前时间戳
使用示例
以下是如何使用 RecentCounter
类的示例:
public class Main {
public static void main(String[] args) {
RecentCounter counter = new RecentCounter();
System.out.println(counter.ping(1)); // 输出: 1
System.out.println(counter.ping(100)); // 输出: 2
System.out.println(counter.ping(3001)); // 输出: 3
System.out.println(counter.ping(3002)); // 输出: 3
}
}
复杂度分析
-
时间复杂度:
ping
方法的时间复杂度为 O(n),最坏情况下需要遍历队列中的所有元素以移除过期的请求。
-
空间复杂度:
- 空间复杂度为 O(n),队列可能会存储最多 n 个请求。
总结
在这篇博客中,我们详细讨论了 LeetCode 第 933 题——Recent Counter 的解决方案。通过使用 Java 的 Queue
数据结构,我们能够高效地管理请求时间戳并计算在给定时间窗口内的请求数量。这一实现不仅简洁明了,而且易于扩展和维护。
希望这篇博客能帮助你更好地理解这个问题。如果你有任何问题或建议,请随时在下方留言!