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 ""
.For example:
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"
import java.util.HashMap;
import java.util.TreeMap;
class TimeMap {
private HashMap<String, TreeMap<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 TreeMap<>());
}
map.get(key).put(timestamp, value);
}
public String get(String key, int timestamp) {
if (!map.containsKey(key)) {
return "";
}
TreeMap<Integer, String> timeMap = map.get(key);
Integer floorKey = timeMap.floorKey(timestamp);
if (floorKey == null) {
return "";
} else {
return timeMap.get(floorKey);
}
}
}
/**
* Your TimeMap object will be instantiated and called as such:
* TimeMap obj = new TimeMap();
* obj.set(key,value,timestamp);
* String param_2 = obj.get(key,timestamp);
*/
A naive solution would be to store the key-value pairs with their timestamps in a list or array. When get
is called, iterate through the list to find the largest timestamp that is less than or equal to the given timestamp.
This would have a time complexity of O(n) for the get operation, where n is the number of entries for a given key.
The optimal solution uses a HashMap to store the keys, and a TreeMap to store the timestamps and values for each key. The TreeMap automatically sorts the timestamps, which allows for efficient retrieval of the value associated with the largest timestamp that is less than or equal to the given timestamp.
set(String key, String value, int timestamp)
: O(log n), where n is the number of entries for a given key. This is because the put
operation in a TreeMap takes O(log n) time.get(String key, int timestamp)
: O(log n), where n is the number of entries for a given key. This is because the floorKey
operation in a TreeMap takes O(log n) time.get
method should return an empty string "".get
method should return an empty string "".get
method should return the value associated with the largest timestamp that is less than or equal to the given timestamp.Here's how the provided code handles these edge cases:
map.containsKey(key)
. If the key does not exist, it returns "".timeMap.floorKey(timestamp)
to find the largest timestamp that is less than or equal to the given timestamp. If no such timestamp exists (i.e., floorKey
returns null
), it returns "".floorKey
method of the TreeMap ensures that the largest timestamp that is less than or equal to the given timestamp is returned. The corresponding value is then returned.