LC.981 | 基于时间的键值存储 | 哈希 | upper_bound快速定位

输入:

  • set(key, value, timestamp)
  • get(key, timestamp)

要求:

  • 同一个 key 在不同 timestamp 可以存多次
  • get 需要返回:timestamp_prev <= timestamp 的最大那次对应的 value
  • 如果不存在返回空串 ""

输出:

  • set:无返回
  • getstring

思路:

这题的核心就是:对每个 key,把 (timestamp -> value) 存起来,并且能快速找“<= timestamp 的最大时间点”。

数据结构选择:

  • 外层:unordered_map<string, ...> 通过 key 快速定位一组记录
  • 内层:map<int, string> 自动按 timestamp 升序存放,支持二分相关操作

get(key, timestamp) 怎么找?

  • upper_bound(timestamp):它返回第一个 > timestamp 的迭代器
  • 那么“<= timestamp 的最大值”就是它的前一个位置
  • 特判两种情况:
    1. 这个 key 压根不存在 -> ""
    2. upper_bound 指向 begin,说明所有 timestamp 都 > 目标 -> ""
    3. 否则 --it 返回答案

复杂度:

  • 时间复杂度:
    • set:O(log M)
    • get:O(log M)
    • 其中 M 是某个 key 下存了多少条记录
  • 空间复杂度:O(总记录数)

class TimeMap {
    unordered_map<string, map<int, string>> m;

public:
    TimeMap() {}

    void set(string key, string value, int timestamp) {
        m[key][timestamp] = value;
    }

    string get(string key, int timestamp) {
        if (m.find(key) == m.end()) return "";

        map<int, string>& time_m = m[key];
        auto it = time_m.upper_bound(timestamp); // first > timestamp

        if (it == time_m.begin()) return "";     // all > timestamp

        --it;                                    // last <= timestamp
        return it->second;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值