LeetCode 题解工作台
基于时间的键值存储
设计一个基于时间的键值数据结构,该结构可以在不同时间戳存储对应同一个键的多个值,并针对特定时间戳检索键对应的值。 实现 TimeMap 类: TimeMap() 初始化数据结构对象 void set(String key, String value, int timestamp) 存储给定时间戳 t…
4
题型
4
代码语言
3
相关题
当前训练重点
中等 · 二分·搜索·答案·空间
答案摘要
我们可以用哈希表 记录键值对,其中键为字符串 ,值为一个有序集合,集合中的每个元素为一个二元组 $(\textit{timestamp}, \textit{value})$,表示键 在时间戳 时对应的值为 。 当我们需要查询键 在时间戳 时对应的值时,我们可以通过有序集合的方法找到最大的时间戳 ,使得 $\textit{timestamp}' \leq \textit{timestamp…
Interview AiBoxInterview AiBox 实时 AI 助手,陪你讲清 二分·搜索·答案·空间 题型思路
题目描述
设计一个基于时间的键值数据结构,该结构可以在不同时间戳存储对应同一个键的多个值,并针对特定时间戳检索键对应的值。
实现 TimeMap 类:
TimeMap()初始化数据结构对象void set(String key, String value, int timestamp)存储给定时间戳timestamp时的键key和值value。String get(String key, int timestamp)返回一个值,该值在之前调用了set,其中timestamp_prev <= timestamp。如果有多个这样的值,它将返回与最大timestamp_prev关联的值。如果没有值,则返回空字符串("")。
示例 1:
输入:
["TimeMap", "set", "get", "get", "set", "get", "get"]
[[], ["foo", "bar", 1], ["foo", 1], ["foo", 3], ["foo", "bar2", 4], ["foo", 4], ["foo", 5]]
输出:
[null, null, "bar", "bar", null, "bar2", "bar2"]
解释:
TimeMap timeMap = new TimeMap();
timeMap.set("foo", "bar", 1); // 存储键 "foo" 和值 "bar" ,时间戳 timestamp = 1
timeMap.get("foo", 1); // 返回 "bar"
timeMap.get("foo", 3); // 返回 "bar", 因为在时间戳 3 和时间戳 2 处没有对应 "foo" 的值,所以唯一的值位于时间戳 1 处(即 "bar") 。
timeMap.set("foo", "bar2", 4); // 存储键 "foo" 和值 "bar2" ,时间戳 timestamp = 4
timeMap.get("foo", 4); // 返回 "bar2"
timeMap.get("foo", 5); // 返回 "bar2"
提示:
1 <= key.length, value.length <= 100key和value由小写英文字母和数字组成1 <= timestamp <= 107set操作中的时间戳timestamp都是严格递增的- 最多调用
set和get操作2 * 105次
解题思路
方法一:哈希表 + 有序集合(或二分查找)
我们可以用哈希表 记录键值对,其中键为字符串 ,值为一个有序集合,集合中的每个元素为一个二元组 ,表示键 在时间戳 时对应的值为 。
当我们需要查询键 在时间戳 时对应的值时,我们可以通过有序集合的方法找到最大的时间戳 ,使得 ,然后返回对应的值即可。
时间复杂度方面,对于 操作,由于哈希表的插入操作的时间复杂度为 ,因此时间复杂度为 。对于 操作,由于哈希表的查找操作的时间复杂度为 ,而有序集合的查找操作的时间复杂度为 ,因此时间复杂度为 。空间复杂度为 ,其中 为 操作的次数。
class TimeMap:
def __init__(self):
self.ktv = defaultdict(list)
def set(self, key: str, value: str, timestamp: int) -> None:
self.ktv[key].append((timestamp, value))
def get(self, key: str, timestamp: int) -> str:
if key not in self.ktv:
return ''
tv = self.ktv[key]
i = bisect_right(tv, (timestamp, chr(127)))
return tv[i - 1][1] if i else ''
# Your TimeMap object will be instantiated and called as such:
# obj = TimeMap()
# obj.set(key,value,timestamp)
# param_2 = obj.get(key,timestamp)
复杂度分析
| 指标 | 值 |
|---|---|
| 时间 | Depends on the final approach |
| 空间 | Depends on the final approach |
面试官常问的追问
外企场景- question_mark
Ask if you can assume timestamps are strictly increasing per key.
- question_mark
Check if the candidate uses binary search instead of linear scan for retrieval.
- question_mark
Confirm handling of keys with no stored value at the queried timestamp.
常见陷阱
外企场景- error
Performing linear search instead of binary search for get operations, leading to timeouts.
- error
Not handling empty lists or keys with no stored timestamps properly.
- error
Incorrectly implementing binary search boundaries, returning the wrong value for edge timestamps.
进阶变体
外企场景- arrow_right_alt
Support deletion of key-value pairs at specific timestamps.
- arrow_right_alt
Allow multiple keys with overlapping timestamp ranges and query across them.
- arrow_right_alt
Retrieve all values within a given timestamp range instead of just the latest one.