Skip to content

Commit 898aa30

Browse files
Add TimeMap implementation with binary search and tests
Implemented a `TimeMap` class featuring `set` and `get` methods to handle time-based key-value storage using binary search for efficient retrieval. Added comprehensive unit tests to validate functionality across multiple scenarios, including edge cases and multiple keys.
1 parent c6a6081 commit 898aa30

File tree

1 file changed

+76
-0
lines changed

1 file changed

+76
-0
lines changed
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# https://neetcode.io/problems/time-based-key-value-store
2+
3+
import unittest
4+
5+
6+
class TimeMap:
7+
def __init__(self):
8+
self.history = {}
9+
10+
def set(self, key: str, value: str, timestamp: int) -> None:
11+
if key not in self.history:
12+
self.history[key] = []
13+
14+
self.history[key].append([value, timestamp])
15+
16+
def get(self, key: str, timestamp: int) -> str:
17+
result = "" # Most recent value for given timestamp
18+
values = self.history.get(key, [])
19+
20+
left = 0
21+
right = len(values) - 1
22+
23+
while left <= right:
24+
mid = (left + right) // 2
25+
26+
prev_timestamp = values[mid][1]
27+
28+
if prev_timestamp <= timestamp:
29+
result = values[mid][0]
30+
31+
left = mid + 1
32+
else:
33+
right = mid - 1
34+
35+
return result
36+
37+
38+
class TestTimeMap(unittest.TestCase):
39+
def setUp(self):
40+
self.time_map = TimeMap()
41+
42+
def test_set_and_get_single_value(self):
43+
self.time_map.set("foo", "bar", 1)
44+
self.assertEqual(self.time_map.get("foo", 1), "bar")
45+
46+
def test_get_most_recent_value(self):
47+
self.time_map.set("foo", "bar", 1)
48+
self.time_map.set("foo", "bar2", 2)
49+
self.assertEqual(self.time_map.get("foo", 2), "bar2")
50+
self.assertEqual(self.time_map.get("foo", 3), "bar2")
51+
52+
def test_get_before_any_set_value(self):
53+
self.assertEqual(self.time_map.get("foo", 1), "")
54+
55+
def test_key_with_multiple_values_and_timestamp(self):
56+
self.time_map.set("key1", "alpha", 1)
57+
self.time_map.set("key1", "beta", 3)
58+
self.time_map.set("key1", "gamma", 5)
59+
60+
# Exact match for timestamps
61+
self.assertEqual(self.time_map.get("key1", 3), "beta")
62+
self.assertEqual(self.time_map.get("key1", 5), "gamma")
63+
64+
# Fetching closest lower timestamp
65+
self.assertEqual(self.time_map.get("key1", 4), "beta")
66+
self.assertEqual(self.time_map.get("key1", 2), "alpha")
67+
68+
# Fetching before the first timestamp
69+
self.assertEqual(self.time_map.get("key1", 0), "")
70+
71+
def test_multiple_keys(self):
72+
self.time_map.set("foo", "bar", 1)
73+
self.time_map.set("baz", "qux", 2)
74+
self.assertEqual(self.time_map.get("foo", 1), "bar")
75+
self.assertEqual(self.time_map.get("baz", 2), "qux")
76+
self.assertEqual(self.time_map.get("baz", 1), "")

0 commit comments

Comments
 (0)