[LeetCode] 981. Time Based Key-Value Store
Design a time-based key-value data structure that can store multiple values for the same key at different time stamps and retrieve the key's value at a certain timestamp.
Implement the TimeMap
class:
TimeMap()
Initializes the object of the data structure.void set(String key, String value, int timestamp)
Stores the keykey
with the valuevalue
at the given timetimestamp
.String get(String key, int timestamp)
Returns a value such thatset
was called previously, withtimestamp_prev <= timestamp
. If there are multiple such values, it returns the value associated with the largesttimestamp_prev
. If there are no values, it returns""
.
Example 1:
Input ["TimeMap", "set", "get", "get", "set", "get", "get"] [[], ["foo", "bar", 1], ["foo", 1], ["foo", 3], ["foo", "bar2", 4], ["foo", 4], ["foo", 5]] Output [null, null, "bar", "bar", null, "bar2", "bar2"] Explanation TimeMap timeMap = new TimeMap(); timeMap.set("foo", "bar", 1); // store the key "foo" and value "bar" along with timestamp = 1. timeMap.get("foo", 1); // return "bar" timeMap.get("foo", 3); // return "bar", since there is no value corresponding to foo at timestamp 3 and timestamp 2, then the only value is at timestamp 1 is "bar". timeMap.set("foo", "bar2", 4); // store the key "foo" and value "bar2" along with timestamp = 4. timeMap.get("foo", 4); // return "bar2" timeMap.get("foo", 5); // return "bar2"
Constraints:
1 <= key.length, value.length <= 100
key
andvalue
consist of lowercase English letters and digits.1 <= timestamp <= 107
- All the timestamps
timestamp
ofset
are strictly increasing. - At most
2 * 105
calls will be made toset
andget
.
基于时间的键值存储。
设计一个基于时间的键值数据结构,该结构可以在不同时间戳存储对应同一个键的多个值,并针对特定时间戳检索键对应的值。
实现 TimeMap 类:
TimeMap() 初始化数据结构对象
void set(String key, String value, int timestamp) 存储键 key、值 value,以及给定的时间戳 timestamp。
String get(String key, int timestamp)
返回先前调用 set(key, value, timestamp_prev) 所存储的值,其中 timestamp_prev <= timestamp 。
如果有多个这样的值,则返回对应最大的 timestamp_prev 的那个值。
如果没有值,则返回空字符串("")。来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/time-based-key-value-store
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
这个题有两种思路,一是用Java的treemap,另一种是用到binary search。
首先第一种思路,用treemap。因为会存在多个键值是同样的key,但是有不同的value和不同的timestamp,所以一开始比较直观的思路一定是hashmap<String, timestamp>,因为hashmap才能存储类似这种<key, value>键值对的数据。其次,题目要求当找到同样的key,同样的value的时候,要返回最接近timestamp的value,所以想到用treemap<timestamp, String>,因为treemap是可以自动根据key排序的。
时间O(logn) - treemap的get和set都是这个复杂度
空间O(n)
Java实现
1 class TimeMap { 2 private HashMap<String, TreeMap<Integer, String>> map; 3 4 /** Initialize your data structure here. */ 5 public TimeMap() { 6 map = new HashMap<>(); 7 } 8 9 public void set(String key, String value, int timestamp) { 10 TreeMap<Integer, String> tmap = map.get(key); 11 if (tmap == null) { 12 tmap = new TreeMap<>(); 13 map.put(key, tmap); 14 } 15 tmap.put(timestamp, value); 16 } 17 18 public String get(String key, int timestamp) { 19 TreeMap<Integer, String> tmap = map.get(key); 20 if (tmap == null) { 21 return ""; 22 } 23 Integer floorKey = tmap.floorKey(timestamp); 24 if (floorKey == null) { 25 return ""; 26 } 27 return tmap.get(floorKey); 28 } 29 } 30 31 /** 32 * Your TimeMap object will be instantiated and called as such: 33 * TimeMap obj = new TimeMap(); 34 * obj.set(key,value,timestamp); 35 * String param_2 = obj.get(key,timestamp); 36 */
第二种思路是用到二分法。在不用treemap的前提下,我们依然需要创建一个hashmap存储key和value(这里会是一个list)的键值对,但是对于value相同但是timestamp不同的数据,我们可以自己创建一个类,把这个类放入list,这样当get key的时候,实际上我们get到的是一个由arraylist串联好的,有相同key的values。当你能得到这个list之后,可以根据给出的变量timestamp找到list中最接近于这个timestamp的键值对。
时间, get - O(1), set - O(logn)
空间O(n)
Java实现
1 class Data { 2 String val; 3 int time; 4 5 Data(String val, int time) { 6 this.val = val; 7 this.time = time; 8 } 9 } 10 11 class TimeMap { 12 Map<String, List<Data>> map; 13 14 /** Initialize your data structure here. */ 15 public TimeMap() { 16 map = new HashMap<String, List<Data>>(); 17 } 18 19 public void set(String key, String value, int timestamp) { 20 if (!map.containsKey(key)) { 21 map.put(key, new ArrayList<Data>()); 22 } 23 map.get(key).add(new Data(value, timestamp)); 24 } 25 26 public String get(String key, int timestamp) { 27 if (!map.containsKey(key)) { 28 return ""; 29 } 30 return binarySearch(map.get(key), timestamp); 31 } 32 33 private String binarySearch(List<Data> list, int timestamp) { 34 int low = 0; 35 int high = list.size() - 1; 36 while (low < high) { 37 int mid = (low + high) / 2; 38 if (list.get(mid).time == timestamp) { 39 return list.get(mid).val; 40 } 41 if (list.get(mid).time < timestamp) { 42 if (list.get(mid + 1).time > timestamp) { 43 return list.get(mid).val; 44 } 45 low = mid + 1; 46 } else { 47 high = mid - 1; 48 } 49 } 50 return list.get(low).time <= timestamp ? list.get(low).val : ""; 51 } 52 } 53 54 /** 55 * Your TimeMap object will be instantiated and called as such: 56 * TimeMap obj = new TimeMap(); 57 * obj.set(key,value,timestamp); 58 * String param_2 = obj.get(key,timestamp); 59 */
相关题目