前言
Weekly Contest 121的 基于时间的键值存储:
创建一个基于时间的键值存储类
TimeMap
,它支持下面两个操作:
set(string key, string value, int timestamp)
- 存储键
key
、值value
,以及给定的时间戳timestamp
。
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, 100]
范围内。- 所有 TimeMap.set 操作中的时间戳
timestamps
都是严格递增的。1 <= timestamp <= 10^7
TimeMap.set
和TimeMap.get
函数在每个测试用例中将(组合)调用总计 120000 次。
解题思路
本题解题前可以去了解一下时序数据库,本题其实就是实现一个简单的时序数据库。同时实现也是很简单:
- 首先定义一个
ValueMap
,该Map
以timestamp
为key
,以value
为value
,这样就能够记录下不同timestamp
下的value
。 - 然后再定义一个
Map
,该Map
以key
为key
,以ValueMap
为value
。
需要注意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 "";
}
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。