前言

Weekly Contest 121基于时间的键值存储

创建一个基于时间的键值存储类 TimeMap,它支持下面两个操作:

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

    • 存储键 key、值 value,以及给定的时间戳 timestamp
  2. get(string key, int timestamp)

    • 返回先前调用 set(key, value, timestamp_prev) 所存储的值,其中 timestamp_prev <= timestamp
    • 如果有多个这样的值,则返回对应最大的 timestamp_prev 的那个值。
    • 如果没有值,则返回空字符串("")。

示例1:

输入: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"]

提示:

  1. 所有的键/值字符串都是小写的。
  2. 所有的键/值字符串长度都在 [1, 100] 范围内。
  3. 所有 TimeMap.set 操作中的时间戳 timestamps 都是严格递增的。
  4. 1 <= timestamp <= 10^7
  5. TimeMap.setTimeMap.get 函数在每个测试用例中将(组合)调用总计 120000 次。

解题思路

本题解题前可以去了解一下时序数据库,本题其实就是实现一个简单的时序数据库。同时实现也是很简单:

  1. 首先定义一个ValueMap,该Maptimestampkey,以valuevalue,这样就能够记录下不同timestamp下的value
  2. 然后再定义一个Map,该Mapkeykey,以ValueMapvalue

需要注意ValueMap我选择的是用TreeMap,其提供firstKey()能够快速找到第一个元素,而floorEntry()则会返回与小于或等于给定键的最大键关联的键值映射,如果没有这样的键,则返回null

实现代码

/**
 * 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 "";
        }
    }
}

Null
137 声望31 粉丝

免费的东西是最贵的,好走的只是下坡路