前言

Weekly Contest 109的第一题 最近的请求次数

写一个 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]

提示:

  1. 每个测试用例最多调用 10000ping
  2. 每个测试用例会使用严格递增的 t 值来调用 ping
  3. 每次调用 ping 都有 1 <= t <= 10^9

解题思路

本题其实并不复杂,但是我在实现时由于思考的方向错了,导致了花费大量时间去完成这个题目。
一开始我的思路是仿照LRU算法,实现一个会移除超出有效范围[t - 3000, t]的缓存。
但是随着不断的尝试后,发现其实只需要统计时有效的ping即可。期间遇到过好几次执行超时的情况,所以需要优化统计有效ping时的检索区间。
所以最终实现思路如下:

  1. 需要一个存储所有ping时间的数组list和记录最小有效ping时间的list索引minIndex
  2. 每次ping就从minIndex开始检索list,直到遇到数组list中的ping时间item有效(即item[t - 3000, t])则中断循环,否则(item<t-3000)minIndex自增。

实现代码

/**
 * 933. 最近的请求次数
 * @author RJH
 * create at 2018/11/4
 */
public class RecentCounter {
    /**
     * 存储ping时间的List
     */
    private List<Integer> 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;
    }
}

Null
137 声望31 粉丝

免费的东西是最贵的,好走的只是下坡路