Weekly Contest 121的 基於時間的鍵值存儲:數據庫
建立一個基於時間的鍵值存儲類
TimeMap
,它支持下面兩個操做:函數
set(string key, string value, int timestamp)
測試
- 存儲鍵
key
、值value
,以及給定的時間戳timestamp
。
get(string key, int timestamp)
code
- 返回先前調用
set(key, value, timestamp_prev)
所存儲的值,其中timestamp_prev <= timestamp
。- 若是有多個這樣的值,則返回對應最大的
timestamp_prev
的那個值。- 若是沒有值,則返回空字符串(
""
)。示例1:leetcode
輸入:inputs = ["TimeMap","set","get","get","set","get","get"], inputs = [[],["foo","bar",1],["foo",1],["foo",3],["foo","bar2",4],["foo",4],["foo",5]] 輸出:[null,null,"bar","bar",null,"bar2","bar2"] 解釋: TimeMap kv; kv.set("foo", "bar", 1); // 存儲鍵 "foo" 和值 "bar" 以及時間戳 timestamp = 1 kv.get("foo", 1); // 輸出 "bar" kv.get("foo", 3); // 輸出 "bar" 由於在時間戳 3 和時間戳 2 處沒有對應 "foo" 的值,因此惟一的值位於時間戳 1 處(即 "bar") kv.set("foo", "bar2", 4); kv.get("foo", 4); // 輸出 "bar2" kv.get("foo", 5); // 輸出 "bar2"示例2:字符串
輸入:inputs = ["TimeMap","set","set","get","get","get","get","get"], inputs = [[],["love","high",10],["love","low",20],["love",5],["love",10],["love",15],["love",20],["love",25]] 輸出:[null,null,null,"","high","high","low","low"]提示:get
- 全部的鍵/值字符串都是小寫的。
- 全部的鍵/值字符串長度都在
[1, 100]
範圍內。- 全部 TimeMap.set 操做中的時間戳
timestamps
都是嚴格遞增的。1 <= timestamp <= 10^7
TimeMap.set
和TimeMap.get
函數在每一個測試用例中將(組合)調用總計 120000 次。
本題解題前能夠去了解一下時序數據庫,本題其實就是實現一個簡單的時序數據庫。同時實現也是很簡單:input
ValueMap
,該Map
以timestamp
爲key
,以value
爲value
,這樣就可以記錄下不一樣timestamp
下的value
。Map
,該Map
以key
爲key
,以ValueMap
爲value
。須要注意ValueMap
我選擇的是用TreeMap
,其提供firstKey()
可以快速找到第一個元素,而floorEntry()
則會返回與小於或等於給定鍵的最大鍵關聯的鍵值映射,若是沒有這樣的鍵,則返回null
。string
/** * 981. 基於時間的鍵值存儲 * @author RJH * create at 2019-01-27 */ public class TimeMap { /** * 將HashMap和TreeMap組合使用 * 使用TreeMap是由於其可以有序的存儲數據,由於其提供的firstKey()和floorEntry()很方便 */ private HashMap<String,TreeMap<Integer,String>> map; /** Initialize your data structure here. */ public TimeMap() { map=new HashMap<>(); } public void set(String key, String value, int timestamp) { //判斷是否存在這個Key if(map.containsKey(key)){ TreeMap<Integer,String> valueMap=map.get(key); //以timpstamp做爲key確保記錄不一樣timestamp下的value valueMap.put(timestamp,value); }else{ //初次記錄該key,初始化ValueMap TreeMap<Integer,String> valueMap=new TreeMap<>(); valueMap.put(timestamp,value); map.put(key,valueMap); } } public String get(String key, int timestamp) { if(map.containsKey(key)){ TreeMap<Integer,String> valueMap=map.get(key); if(valueMap.containsKey(timestamp)){ return valueMap.get(timestamp); }else{ //須要防止輸入的timestamp比存儲的timestamp都要小的狀況 if(timestamp<valueMap.firstKey()){ return ""; }else{ return valueMap.floorEntry(timestamp).getValue(); } } }else{ return ""; } } }