Back to Binary Search
Medium
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.
Examples
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"]
TimeMap timeMap = new TimeMap();
timeMap.set("foo", "bar", 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);
timeMap.get("foo", 4); // return "bar2"
timeMap.get("foo", 5); // return "bar2"
Constraints
1 <= key.length, value.length <= 100key and value consist of lowercase English letters and digits.1 <= timestamp <= 10^7All the timestamps timestamp of set are strictly increasing.At most 2 * 10^5 calls will be made to set and get.
Hash Map + Binary Search
Approach
Since `set` is called with strictly increasing timestamps, we can store values in a hash map where the key is the string `key`, and the value is a list of `[value, timestamp]` pairs. This list will automatically be sorted by timestamp. For `get`, we can use binary search on this list to find the value with the largest timestamp that is `<= target_timestamp`.
Complexity Analysis
Time Complexity
O(1) for set, O(log N) for get
Space Complexity
O(N)
N is the number of set operations.
Solution.java
class TimeMap { private Map<String, List<Pair<Integer, String>>> map;
public TimeMap() { map = new HashMap<>(); } public void set(String key, String value, int timestamp) { if (!map.containsKey(key)) { map.put(key, new ArrayList<>()); } map.get(key).add(new Pair(timestamp, value)); } public String get(String key, int timestamp) { if (!map.containsKey(key)) { return ""; } List<Pair<Integer, String>> list = map.get(key); int left = 0; int right = list.size() - 1; String res = ""; while (left <= right) { int mid = left + (right - left) / 2; if (list.get(mid).getKey() <= timestamp) { res = list.get(mid).getValue(); left = mid + 1; // Search for a closer, larger timestamp } else { right = mid - 1; } } return res; }}// Note: Pair class assumed for Java (custom or javafx.util.Pair)class Pair<K, V> { K key; V value; public Pair(K key, V value) { this.key = key; this.value = value; } public K getKey() { return key; } public V getValue() { return value; }}