theme: smartblue
持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第4天,点击查看活动详情
最近的请求次数
题目解析
题目难度:简单
题目素材解析
从题目的描述来看,只提供了一个素材。
- 提供了时间t参数。
并且保证多次调用ping方法时,t的值一直会递增;也就是说每一次执行ping方法时,t的值相对来说都是最大的。
我的解读
我对本道题的解读,其实也并不难理解。
其实预期结果就是,在执行ping方法时,要计算出当前对象实例的历史ping方法传入的历史值,有多少个是在[t-3000, t]内。
就是这个示例可能会比较迷惑。
比如下面这个:
输入: ["RecentCounter", "ping", "ping", "ping", "ping"] [[], [1], [100], [3001], [3002]]
这里要简单说一下,第一行是执行方法或者new对象;
第二行是传入的参数。
解题思路
由上面的解读,来解答一下这道题的思路:
一共分为两个关键点:
其一,保存历史值。
其二,从历史值中获得符合要求值的个数。
初版代码中,是通过List来存储历史值,并且通过暴力循环的方式来获得结果个数。
完善代码中,也是通过List来存储历史值,不过因为优化的工作在其中,利用二分法来获得最终位置,以此来计算结果个数。
代码
初版代码:
```java class RecentCounter {
List<Integer> list = null;
public RecentCounter() {
list = new ArrayList<>();
}
public int ping(int t) {
list.add(t);
int a = 0;
int mint = t - 3000;
for (Integer tb : list) {
if (tb >= mint) {
a += 1;
}
}
return a;
}
} ``` 完善后的代码:
```java class RecentCounter {
List<Integer> list = null;
public RecentCounter() {
list = new ArrayList<>();
}
public int ping(int t) {
list.add(t);
int mint = t - 3000;
int l = 0, r = list.size();
while (l < r){
int n = (r + l) / 2;
Integer tb = list.get(n);
if (tb >= mint) {
r = n;
}else{
l = n + 1;
}
}
return list.size() - l;
}
} ```
执行结果
前期使用的方法是通过暴力循环来解决的,所以效率比较慢;
使用二分法完善后的执行结果,明显会好一些,但是终究是没有队列处理的更快。
Java代码本地执行
Java本地可调试代码,请参考github/Ijiran,可通过索引看到相应代码。