[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 key key with the value value at the given time timestamp.
  • String get(String key, int timestamp) Returns a value such that set was called previously, with timestamp_prev <= timestamp. If there are multiple such values, it returns the value associated with the largest timestamp_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 and value consist of lowercase English letters and digits.
  • 1 <= timestamp <= 107
  • All the timestamps timestamp of set are strictly increasing.
  • At most 2 * 105 calls will be made to set and get.

基于时间的键值存储。

设计一个基于时间的键值数据结构,该结构可以在不同时间戳存储对应同一个键的多个值,并针对特定时间戳检索键对应的值。

实现 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  */

 

相关题目

981. Time Based Key-Value Store

2034. Stock Price Fluctuation

LeetCode 题目总结

posted @ 2020-05-16 04:30  CNoodle  阅读(254)  评论(0编辑  收藏  举报