###### tags: `LeetCode` `Medium` `Binary Search` # LeetCode #981 [Time Based Key-Value Store](https://leetcode.com/problems/time-based-key-value-store/) ### (Medium) 設計一個基於時間的鍵值數據結構,該結構可以在不同時間戳存儲對應同一個鍵的多個值,並針對特定時間戳檢索鍵對應的值。 實現 TimeMap 類: ``` TimeMap() 初始化數據結構對象 void set(String key, String value, int timestamp) 存儲鍵 key、值 value,以及給定的時間戳 timestamp。 String get(String key, int timestamp) 返回先前調用 set(key, value, timestamp_prev) 所存儲的值,其中 timestamp_prev <= timestamp 。 ``` 如果有多個這樣的值,則返回對應最大的  timestamp_prev 的那個值。 如果沒有值,則返回空字符串("")。 --- 首先, 儲存的資料格式為Key-value-time, 但是因為要用time來找到時間最接近的timestamp, 所以資料的儲存格式為unordered_map<key, map<timestamp, value>>。 set function:單純將(timestamp, value)存入s[key]中。 get function:首先先確定key值存在, 若不存在返回""。再來尋找timestamp值大於要求時間的value, 若找到的指標為map的begin, 則代表map中所有的timestamp皆大於指定時間, 找不到符合的資料, 因此回傳""。若不為begin, 則代表至少有一筆資料符合, 此時返回指標的前一個位置的value(也就是所有timestamp滿足條件的資料中, timestamp值最大-最新的那一筆)。 --- ``` class TimeMap { public: unordered_map<string, map<int, string>> s; TimeMap() { } void set(string key, string value, int timestamp) { s[move(key)].emplace(timestamp, move(value)); } string get(string key, int timestamp) { auto m = s.find(key); if(m==s.end())return ""; auto it = m->second.upper_bound(timestamp); if(it==m->second.begin())return ""; return prev(it)->second; } }; /** * Your TimeMap object will be instantiated and called as such: * TimeMap* obj = new TimeMap(); * obj->set(key,value,timestamp); * string param_2 = obj->get(key,timestamp); */ ```