最近的請求次數
題目描述
寫一個 RecentCounter 類來計算最近的請求。
它只有一個方法:ping(int t),其中 t 代表以毫秒為單位的某個時間。
返回從 3000 毫秒前到現在的 ping 數。
任何處于 [t - 3000, t] 時間范圍之內的 ping 都將會被計算在內,包括當前(指 t 時刻)的 ping。
保證每次對 ping 的調用都使用比之前更大的 t 值。
示例 1:
輸入: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。
解題思路
首先得理解題目的意思,題目的要求是計算最近(3000毫秒)的請求數,也就是說 ping 方法會接收一個輸入參數 t ,這個 t 表示現在的時間,要求返回離時間 t 最近 3000 毫秒之內的請求數。以上文所述的示例為例:
輸入:[],輸出:null。這個不用管,應該是進行初始化的工作。
輸入:1,輸出:1。離 1 最近 3000 毫秒的時間段為[0,1],因此請求數為 1。
輸入:100,輸出:2。離 100 最近 3000 毫秒的時間段為[0,100],因此算上之前時間 1 和現在的時間 100 的請求,總請求數為 2。
輸入:3001,輸出:3。離 3001 最近 3000 毫秒的時間段為[1,3001],因此總請求數為 3(分別為在 1,100,3001 時間的請求)。
輸入:3002,輸出:3。離 3002 最近 3000 毫秒的時間段為[2,3002],因此之前時間 1 的請求已經不能計算在內了,所以總請求數還是為 3。
理解了題意之后,這道題就比較好解了,因為它要過濾掉之前的請求,因此我們很容易就能想到利用隊列這種先進先出的結構來進行過濾,把每次請求的時間存儲在隊列中,然后將最早一批請求的時間和當前時間進行對比,如果它在當前時間 3000 毫秒之前,就將該請求記錄給移除,這樣就能確保返回正確的請求次數了。
復雜度分析
- 時間復雜度:O(n),其中 n 是 ping 的次數。
- 空間復雜度:O(C),其中 C = 3000,因為隊列中最多會存儲 3000 條記錄(每一毫秒請求一次)。
代碼實現
class RecentCounter {
Queue<Integer> queue;
public RecentCounter() {
queue = new LinkedList();
}
public int ping(int t) {
queue.add(t);
while (queue.peek() < t - 3000) {
queue.poll();
}
return queue.size();
}
}
/**
* Your RecentCounter object will be instantiated and called as such:
* RecentCounter obj = new RecentCounter();
* int param_1 = obj.ping(t);
*/