|
1 | 1 | #![allow(dead_code)]
|
2 |
| -struct TimeMap {} |
| 2 | +use std::collections::HashMap; |
3 | 3 |
|
4 | 4 | /**
|
5 |
| - * `&self` means the method takes an immutable reference. |
6 |
| - * If you need a mutable reference, change it to `&mut self` instead. |
| 5 | + * Your TimeMap object will be instantiated and called as such: |
| 6 | + * let obj = TimeMap::new(); |
| 7 | + * obj.set(key, value, timestamp); |
| 8 | + * let ret_2: String = obj.get(key, timestamp); |
7 | 9 | */
|
| 10 | +struct TimeMap { |
| 11 | + hm: HashMap<String, Vec<(String, i32)>>, |
| 12 | +} |
| 13 | + |
8 | 14 | impl TimeMap {
|
9 | 15 | fn new() -> Self {
|
10 |
| - TimeMap {} |
| 16 | + Self { hm: HashMap::new() } |
11 | 17 | }
|
12 | 18 |
|
13 |
| - fn set(&self, key: String, value: String, timestamp: i32) {} |
| 19 | + fn set(&mut self, key: String, value: String, timestamp: i32) { |
| 20 | + self.hm.entry(key).or_default().push((value, timestamp)); |
| 21 | + } |
14 | 22 |
|
15 | 23 | fn get(&self, key: String, timestamp: i32) -> String {
|
16 |
| - "".to_string() |
| 24 | + let mut res = String::new(); |
| 25 | + |
| 26 | + if let Some(t_list) = self.hm.get(&key) { |
| 27 | + let (mut l, mut r) = (0, t_list.len()); |
| 28 | + |
| 29 | + while l < r { |
| 30 | + let m = l + (r - l) / 2; |
| 31 | + if timestamp < t_list[m].1 { |
| 32 | + r = m; |
| 33 | + } else { |
| 34 | + res = t_list[m].0.clone(); |
| 35 | + l = m + 1; |
| 36 | + } |
| 37 | + } |
| 38 | + } |
| 39 | + |
| 40 | + res |
17 | 41 | }
|
18 | 42 | }
|
19 | 43 |
|
20 |
| -/** |
21 |
| - * Your TimeMap object will be instantiated and called as such: |
22 |
| - * let obj = TimeMap::new(); |
23 |
| - * obj.set(key, value, timestamp); |
24 |
| - * let ret_2: String = obj.get(key, timestamp); |
25 |
| - */ |
| 44 | +/* |
| 45 | + Algorithm - Binary Search |
| 46 | +
|
| 47 | + - Create a HashMap with key as String and value as Vec<(String, i32)> |
| 48 | + - set(key, value, timestamp) |
| 49 | + - Insert the key into the HashMap if it doesn't exist |
| 50 | + - Push the value and timestamp into the Vec |
| 51 | + - get(key, timestamp) |
| 52 | + - If the key doesn't exist, return empty string |
| 53 | + - If the key exists, do binary search on the Vec<(String, i32)> |
| 54 | + - If the timestamp is less than the middle element's timestamp, search the left half |
| 55 | + - If the timestamp is greater than or equal to the middle element's timestamp, search the right half |
| 56 | + - If the timestamp is equal to the middle element's timestamp, return the value |
| 57 | + - If the timestamp is greater than the middle element's timestamp, return the value of the right element |
| 58 | + - If the timestamp is less than the middle element's timestamp, return the value of the left element |
| 59 | +
|
| 60 | + Time O(logN) |
| 61 | + Space O(N) |
| 62 | +*/ |
26 | 63 |
|
27 | 64 | #[cfg(test)]
|
28 | 65 | mod tests {
|
29 | 66 | use super::*;
|
30 | 67 |
|
31 | 68 | #[test]
|
32 |
| - fn test_981() { |
33 |
| - let obj = TimeMap::new(); |
| 69 | + fn test_1() { |
| 70 | + let mut obj = TimeMap::new(); |
34 | 71 | obj.set("foo".to_string(), "bar".to_string(), 1);
|
35 | 72 | assert_eq!(obj.get("foo".to_string(), 1), "bar".to_string());
|
36 | 73 | assert_eq!(obj.get("foo".to_string(), 3), "bar".to_string());
|
|
0 commit comments