981. Time Based Key-Value Store
Medium
Create a timebased key-value store class TimeMap
, that supports two operations.
1. set(string key, string value, int timestamp)
- Stores the
key
andvalue
, along with the giventimestamp
.
2. get(string key, int timestamp)
- Returns a value such that
set(key, value, timestamp_prev)
was called previously, withtimestamp_prev <= timestamp
. - If there are multiple such values, it returns the one with the largest
timestamp_prev
. - If there are no values, it returns the empty string (
""
).
Example 1:
Input: inputs = ["TimeMap","set","get","get","set","get","get"], inputs = [[],["foo","bar",1],["foo",1],["foo",3],["foo","bar2",4],["foo",4],["foo",5]] Output: [null,null,"bar","bar",null,"bar2","bar2"] Explanation: TimeMap kv; kv.set("foo", "bar", 1); // store the key "foo" and value "bar" along with timestamp = 1 kv.get("foo", 1); // output "bar" kv.get("foo", 3); // output "bar" since there is no value corresponding to foo at timestamp 3 and timestamp 2, then the only value is at timestamp 1 ie "bar" kv.set("foo", "bar2", 4); kv.get("foo", 4); // output "bar2" kv.get("foo", 5); //output "bar2"
Example 2:
Input: 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]] Output: [null,null,null,"","high","high","low","low"]
Note:
- All key/value strings are lowercase.
- All key/value strings have length in the range
[1, 100]
- The
timestamps
for allTimeMap.set
operations are strictly increasing. 1 <= timestamp <= 10^7
TimeMap.set
andTimeMap.get
functions will be called a total of120000
times (combined) per test case.
//C++ class TimeMap { map<string, vector<pair<int, string>>> mp; void insert(vector<pair<int, string>>& vec, int ts, string value){ int n = vec.size(), l = 0, r = n-1; auto it = vec.begin(); int m;//the first timestamp > st, if not exist m = n while(l<=r){ m = (l+r)/2; if(m<0||m>=n) break; if((it+m)->first>ts && (m>0 || (it+m-1)->first<=ts)) break; if((it+m)->first>ts) r = m-1; else l = m+1; } if(!(m>=0 && m<n && (it+m)->first>ts && (m>0 || (it+m-1)->first<=ts))) m = n; vec.insert(it+m, pair<int, string>(ts, value)); } string search(vector<pair<int, string>>& vec, int ts){ int n = vec.size(), l = 0, r = n-1; int m;//the last (it+m)->first<=ts; auto it = vec.begin(); while(l<=r) { m = (l+r)/2; if(m<0||m>=n) break; if((it+m)->first<=ts && (m==n-1 || (it+m+1)->first>ts)) break; if((it+m)->first<=ts) l = m+1; else r = m-1; } if(m>=0 && m<n && (it+m)->first<=ts && (m==n-1 || (it+m+1)->first>ts)) return (it+m)->second; return ""; } public: /** Initialize your data structure here. */ TimeMap() { } void set(string key, string value, int timestamp) { if(mp.count(key)==0) mp[key] = vector<pair<int, string>>(); insert(mp[key], timestamp, value); } string get(string key, int timestamp) { return search(mp[key], timestamp); } }; //Java class TimeMap { Map<String, TreeMap<Integer, String>> map; /** Initialize your data structure here. */ public TimeMap() { map = new HashMap<>(); } public void set(String key, String value, int timestamp) { map.computeIfAbsent(key, k -> new TreeMap<Integer, String>()).put(timestamp, value); } public String get(String key, int timestamp) { if(!map.containsKey(key)) return ""; Integer floor = map.get(key).floorKey(timestamp);//key<=timestamp; if(floor == null) return ""; return map.get(key).get(floor); } } /** * 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); */
No comments:
Post a Comment