这是我参与新手入门的第3篇文章
一、题目描述:
创建一个基于时间的键值存储类 TimeMap,它支持下面两个操作:
- 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 的那个值。 如果没有值,则返回空字符串("")。
示例 :
输入: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 次。
二、思路分析:
实现思路
- 使用 哈希表 记录 key 对应的数据
- 提示中提到 set 操作的时间戳 timestamps 是严格递增的, 因此可以使用二分查找
查看题解后发现可以使用 HashMap + TreeMap , 直接调用 TreeMap 的 floorEntry Api 获取结果
遇到的问题
二分查找,边界问题处理
三、AC 代码
哈希表 + 二分查找
class TimeMap {
/** Initialize your data structure here. */
class Node{
String value;
int timestamp;
Node(String value, int timestamp){
this.value = value;
this.timestamp = timestamp;
}
}
Map<String, List<Node>> map;
public TimeMap() {
map = new HashMap<>();
}
public void set(String key, String value, int timestamp) {
Node node = new Node(value, timestamp);
List<Node> list = map.getOrDefault(key, new ArrayList<>());
list.add(node);
map.put(key, list);
}
public String get(String key, int timestamp) {
List<Node> list = map.get(key);
if(list == null || list.size() == 0){
return "";
}
int left = 0;
int right = list.size() -1 ;
int mid = 0;
while(left < right){
mid = left + right + 1 >> 1;
if(list.get(mid).timestamp <= timestamp){
left = mid ;
}else{
right = mid - 1;
}
}
Node ans = list.get(right);
return ans.timestamp <= timestamp ? ans.value : "";
}
}
哈希表 + TreeMap
class TimeMap {
/** Initialize your data structure here. */
class Node{
String value;
int timestamp;
Node(String value, int timestamp){
this.value = value;
this.timestamp = timestamp;
}
}
Map<String, TreeMap<Integer, Node>> map;
public TimeMap() {
map = new HashMap<>();
}
public void set(String key, String value, int timestamp) {
Node node = new Node(value, timestamp);
TreeMap<Integer, Node> treeMap = map.getOrDefault(key, new TreeMap<>());
treeMap.put(timestamp, node);
map.put(key,treeMap);
}
public String get(String key, int timestamp) {
TreeMap<Integer, Node> treeMap = map.getOrDefault(key, new TreeMap<>());
Map.Entry<Integer, Node> entry = treeMap.floorEntry(timestamp);
if(entry == null){
return "";
}
Node ans = entry.getValue();
return ans.timestamp <= timestamp ? ans.value : "";
}
}