題目描述
寫一個 RecentCounter 類來計算特定時間範圍內最近的請求。
請你實現 RecentCounter 類:
- RecentCounter() 初始化計數器,請求數爲 0 。
- int ping(int t) 在時間 t 添加一個新請求,其中 t 表示以毫秒爲單位的某個時間,並返回過去 3000 毫秒內發生的所有請求數(包括新請求)。確切地說,返回在 [t-3000, t] 內發生的請求數。
保證每次對 ping 的調用都使用比之前更大的 t 值。
示例 1:
["RecentCounter", "ping", "ping", "ping", "ping"]
[[], [1], [100], [3001], [3002]]
輸出:
[null, 1, 2, 3, 3]
解釋:
RecentCounter recentCounter = new RecentCounter();
recentCounter.ping(1); // requests = [1],範圍是 [-2999,1],返回 1
recentCounter.ping(100); // requests = [1, 100],範圍是 [-2900,100],返回 2
recentCounter.ping(3001); // requests = [1, 100, 3001],範圍是 [1,3001],返回 3
recentCounter.ping(3002); // requests = [1, 100, 3001, 3002],範圍是 [2,3002],返回 3
提示:
- 1 <= t <= 109
- 保證每次對 ping 調用所使用的 t 值都 嚴格遞增
- 至多調用 ping 方法 104 次
來源:力扣(LeetCode)
鏈接:https://leetcode.cn/problems/number-of-recent-calls
著作權歸領釦網絡所有。商業轉載請聯繫官方授權,非商業轉載請註明出處。
解題思路
首先我們來看描述,貌似不是很懂,直接看實例。
就是生成一個對象,這個對象有個方法,每次調用這個方法並輸入 t,t 是嚴格遞增的。t 會進行保存,然後這個方法返回保存的數據中,返回在 [t-3000, t] 內的數量,其實就是看 t 值是否大於 t-3000。
因爲輸入數據是從小到大依次遞增,是有序的數據,根據題意,我們可以採用隊列來保存數據 t。每次運行時將 t 入隊;然後循環隊列,如果有 小於 t-3000 的,即不再 [t-3000, t] 內,則出隊。循環完返回隊列的長度就是在這個範圍內請求的次數。
先請求,先過期,對應隊列:先進先出。
解題代碼
var RecentCounter = function() {
// 創建一個隊列
this.queue = []
};
/**
* @param {number} t
* @return {number}
*/
RecentCounter.prototype.ping = function(t) {
// 直接入隊
this.queue.push(t)
// 遍歷隊頭是否在範圍內(小於 t-3000 就不在範圍內)
while(this.queue[0] < t-3000){
// 不在就出隊
this.queue.shift()
}
// 隊列的長度就是在範圍內的數量
return this.queue.length
};
/**
* Your RecentCounter object will be instantiated and called as such:
* var obj = new RecentCounter()
* var param_1 = obj.ping(t)
*/
複雜度分析
時間複雜度:均攤 O(1),每個元素至多入隊出隊各一次
空間複雜度:O(L),其中 L 爲隊列的最大元素個數。