难度简单52收藏分享切换为英文关注反馈
写一个 RecentCounter
类来计算最近的请求。
它只有一个方法:ping(int t)
,其中 t
代表以毫秒为单位的某个时间。
返回从 3000 毫秒前到现在的 ping
数。
任何处于 [t - 3000, t]
时间范围之内的 ping
都将会被计算在内,包括当前(指 t
时刻)的 ping
。
保证每次对 ping
的调用都使用比之前更大的 t
值。
示例:
输入:inputs = ["RecentCounter","ping","ping","ping","ping"], inputs = [[],[1],[100],[3001],[3002]] 输出:[null,1,2,3,3]
提示:
- 每个测试用例最多调用
10000
次ping
。 - 每个测试用例会使用严格递增的
t
值来调用ping
。 - 每次调用
ping
都有1 <= t <= 10^9
。
题解:
这道题就是一个阅读理解题,所以这可能就是这道题为什么有那么多踩吧。(没错我也踩了)。
第一个inputs代表电话打出的记录,第二个inputs表示电话打出的时间,所以可以理解为:
[“RecentCouter”] 与 [null] 不需要考虑
第一个 ping声 出现的时间为 1毫秒,
第二个 ping声 出现的时间为 100毫秒,
第三个 ping声 出现的时间为 300毫秒,
第四个 ping声 出现的时间为 3002毫秒。
那么就要计算的是在当前ping声出现的时间及其前3000毫秒出现了多少次 ping 声。如果把当前ping声出现的时间记做 t ,那么就要找出(t-3000)毫秒至t毫秒之间的 ping声有多少次。再次之前我们需要明确开始时间是0毫秒所以时间没有负数即 if(t -3000 < 0) t = 0;那么我来分析之前的那个例子,
当 t = 1, 时间范围就为 (0~1), 那么符合此条件的ping声时间包括 [1毫秒] 所以结果就是 1
当 t = 100, 时间范围就为 (0~100), 那么符合此条件的ping声时间包括 [1毫秒,100毫秒] 所以结果就是 2
当 t = 3001, 时间范围就为 (1~3001), 那么符合此条件的ping声时间包括 [1毫秒,100毫秒,3001毫秒] 所以结果就是 3
当 t = 3002, 时间范围就为 (2~3002), 那么符合此条件的ping声时间包括 [100毫秒,3001毫秒,3002毫秒] 所以结果就是 3
了解了题目意思,我们就能继续接下来的解题。
首先RecentCounter()是一个构造函数,根据算法的不同,有些会用到而有些不会。在我的方法中我建立了一个队列 来方便后续运算。然后我们就能在队列里面进行运算了。
Queue<Integer> queue;
public RecentCounter() {
queue = new LinkedList<Integer>();
}
接下来我们看看第二个函数public int Ping(int t) { },在这里会处理第二个inputs 传入的值(在上面的例子里为 [[],[1],[100],[3001],[3002]])。
首先我们需要把传入的值放入之前定义好的队列中:
queue.add(t);
这样一来依据我们输入的值可以得到不同长度的队列queue。
List<int> l = new List<int>() {} ;
input: 1
output: l = {1}
input: 100
output: l = {1,100}
input: 3001
output: l = {1,100,3001}
input: 3002
output: l = {1,100,3001,3002}
过程分析
之前我一直理解为一次传入,后来理解了发现是一次一次地传入,所以每次运行此函数都会返回一个值,在网页中会自动把结果整理成一个数组,理解这一点就没有那么迷惑了。
当 input = 1
queue = {1}
按照之前我们理解的意思,我们需要找到 l 中所有大于等于 0( 原为1 - 3000,但是时间没有负数,所以返回0,上面讨论过) 并且小于等于1的数的总个数。我们遍历 l发现有1个数,所以返回 1.
当 input = 100
queue = {1,100} (1为上一步所加进的)
这次我们要找到l中大于等于0 (100-3000 = -2900 => 0)且小于等于100的值,这里有2个,所以返回2 。
当 input = 3001
queue = {1,100,3001}
这次我们要找到l中大于等于1(3001- 3000 = 1)且小于等于3001的个数,这里为3,所以返回3。
当 input = 3002
queue = {1,100,3001,3002}
找到 大于等于2小于等于3002的个数为3(100,3001,3002),所以返回3。
完整代码:
class RecentCounter {
Queue<Integer> queue;
public RecentCounter() {
queue = new LinkedList<Integer>();
}
public int ping(int t) {
queue.add(t);
while (queue.peek() < t-3000) {
queue.poll();
}
return queue.size();
}
}