981-基於時間的鍵值存儲

前言

Weekly Contest 121基於時間的鍵值存儲數據庫

建立一個基於時間的鍵值存儲類 TimeMap,它支持下面兩個操做:函數

  1. set(string key, string value, int timestamp)測試

    • 存儲鍵 key、值 value,以及給定的時間戳 timestamp
  2. 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. 全部的鍵/值字符串都是小寫的。
  2. 全部的鍵/值字符串長度都在 [1, 100] 範圍內。
  3. 全部 TimeMap.set 操做中的時間戳 timestamps 都是嚴格遞增的。
  4. 1 <= timestamp <= 10^7
  5. TimeMap.setTimeMap.get 函數在每一個測試用例中將(組合)調用總計 120000 次。

解題思路

本題解題前能夠去了解一下時序數據庫,本題其實就是實現一個簡單的時序數據庫。同時實現也是很簡單:input

  1. 首先定義一個ValueMap,該Maptimestampkey,以valuevalue,這樣就可以記錄下不一樣timestamp下的value
  2. 而後再定義一個Map,該Mapkeykey,以ValueMapvalue

須要注意ValueMap我選擇的是用TreeMap,其提供firstKey()可以快速找到第一個元素,而floorEntry()則會返回與小於或等於給定鍵的最大鍵關聯的鍵值映射,若是沒有這樣的鍵,則返回nullstring

實現代碼

/**
 * 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 "";
        }
    }
}
相關文章
相關標籤/搜索