写一个 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。
解题思路
本题其实并不复杂,但是我在实现时由于思考的方向错了,导致了花费大量时间去完成这个题目。
一开始我的思路是仿照LRU算法,实现一个会移除超出有效范围[t - 3000, t]的缓存。
但是随着不断的尝试后,发现其实只需要统计时有效的ping即可。期间遇到过好几次执行超时的情况,所以需要优化统计有效ping时的检索区间。
所以最终实现思路如下:
需要一个存储所有ping时间的数组list和记录最小有效ping时间的list索引minIndex
每次ping就从minIndex开始检索list,直到遇到数组list中的ping时间item有效(即item在[t - 3000, t])则中断循环,否则(item<t-3000)minIndex自增。
实现代码
/**
-
- 最近的请求次数
-
@author RJH
-
create at 2018/11/4
/
public class RecentCounter {
/*- 存储ping时间的List
/
private List list;
/* - 最小有效ping时间的索引
*/
private int minIndex=0;
public RecentCounter() {
list=new LinkedList<>();
}public int ping(int t) {
list.add(t);
for(int i=minIndex;i<list.size();i++){//从minIndex开始遍历List
Integer item=list.get(i);
if(item<t-3000){//判断最小的有效ping时间是否无效
++minIndex;
}else{
break;
}
}
//返回有效的元素个数
return list.size()-minIndex;
}
} - 存储ping时间的List