Write a class that allows getting and setting key-value pairs, however a time until expiration is associated with each key.
The class has three public methods:
set(key, value, duration)
: accepts an integer key
, an integer value
, and a duration
in milliseconds. Once the duration
has elapsed, the key should be inaccessible. The method should return true if the same un-expired key already exists and false otherwise. Both the value and duration should be overwritten if the key already exists.
get(key)
: if an un-expired key exists, it should return the associated value. Otherwise it should return -1.
count()
: returns the count of un-expired keys.
中文說明 set(key, value, duration)
: 接受一個整數的 key、一個整數值 value,以及一個毫秒為單位的時間 duration。當持續時間結束後,這個鍵值對將不能被存取。如果相同且未過期的鍵存在,則回傳 true,若不存在則回傳 false。如果這個鍵已經存在,其值與持續時間都應該被新傳入的 value 與 duration 覆寫。get(key)
:如果存在未過期的鍵,回傳其對應的值。若沒有相對應的鍵,則回傳 -1。count()
:回傳現存未過期的鍵的總數量。
解題思路: 1.理解題目需求: 要做一個可以「設定時間限制」的快取(cache)。 支援三個方法: set(key, value, duration):設定一個緩存,並在 duration 毫秒後自動移除。 get(key):獲取緩存的值,若該緩存過期則返回 -1。 count():返回當前未過期的緩存數量。 2.使用 Map ,查找 (get) 和新增 (set) 都很快。
解題 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 var TimeLimitedCache = function ( ) { this .cache = new Map () }; TimeLimitedCache .prototype .set = function (key, value, duration ) { const found = this .cache .has (key); if (found){ clearTimeout (this .cache .get (key).timerId ); } this .cache .set (key,{ value, timerId : setTimeout (()=> this .cache .delete (key),duration) }) return found }; TimeLimitedCache .prototype .get = function (key ) { if (this .cache .has (key)){ return this .cache .get (key).value ; }else { return -1 ; } }; TimeLimitedCache .prototype .count = function ( ) { return this .cache .size ; };
補充說明
為什麼存在(found)時要 clearTimeout? 假設緩存中已有鍵 key,且其倒計時尚未結束:
如果直接覆蓋而不清除舊的 setTimeout 計時器,舊計時器仍然會在原定的時間觸發刪除操作。
清除舊的計時器 (clearTimeout) 可以避免多餘的操作,確保新的計時器能正確控制過期時間。
setTimeout 的參數作用是什麼?
1 2 timerId : setTimeout (() => this .cache .delete (key), duration)
setTimeout 的參數是一個回調函數:
() => this.cache.delete(key)
:當計時器觸發時,執行刪除操作。
duration:計時器的延遲時間(以毫秒為單位),指定在多長時間後執行該回調。
setTimeout 確保鍵在 duration 毫秒後自動過期並刪除。
可應用實際案例: 特別適合需要管理短期數據的應用場景,例如緩存用戶會話、臨時配置或頻繁變化的數據
例如,可以使用 TimeLimitedCache 來緩存 API 的回應結果。這樣一來能減少對後端的請求次數。例如,當多個用戶請求相同數據時,可以快速返回緩存結果,而不必每次都發送請求。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 import React , { useEffect, useState } from 'react' ;import TimeLimitedCache from './timeLimitedCache.js' ;const apiCache = new TimeLimitedCache ();const fetchWithCache = async (url, ttl = 5000 ) => { const cachedResponse = apiCache.get (url); if (cachedResponse !== -1 ) { console .log ('Fetching from cache:' , url); return cachedResponse; } const response = await fetch (url); const data = await response.json (); apiCache.set (url, data, ttl); return data; }; const App = ( ) => { const [data, setData] = useState (null ); const [loading, setLoading] = useState (true ); useEffect (() => { const fetchData = async ( ) => { setLoading (true ); const apiUrl = 'https://jsonplaceholder.typicode.com/posts/1' ; const result = await fetchWithCache (apiUrl, 10000 ); setData (result); setLoading (false ); }; fetchData (); }, []); if (loading) return <div > Loading...</div > ; return ( <div > <h1 > Post Details</h1 > <p > <strong > Title:</strong > {data.title}</p > <p > <strong > Body:</strong > {data.body}</p > </div > ); }; export default App ;
補充可以使用 class 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 class TimeLimitedCache { constructor ( ) { this .cache = new Map (); } set (key, value, duration ) { const found = this .cache .has (key); if (found) { clearTimeout (this .cache .get (key).timerId ); } this .cache .set (key, { value, value, timerId : setTimeout (() => { this .cache .delete (key); }, duration), }); return found; } get (key ) { return this .cache .has (key) ? this .cache .get (key).value : -1 ; } count ( ) { return this .cache .size ; } }
參考資料[Medium] LeetCode JS 30 - 2622. Cache with Time Limit LeetCode JS30-Day17 | 2622. Cache With Time Limit 有時間限制的緩存Cache