LeetCode 981. 基于时间的键值存储

博客讨论了一种使用哈希表和二分查找实现的数据结构,用于存储字符串及其对应的时间戳。作者遇到超时问题,起初的实现未能通过所有测试用例。经过优化,如将查找第一个大于等于时间戳的元素改为查找最后一个小于等于时间戳的元素,以及将结构体替换为pair,并调整了查找函数参数为引用,但仍然超时。最终发现,问题在于传入vector副本导致的额外时间消耗。通过使用引用避免副本,成功解决了超时问题。
摘要由CSDN通过智能技术生成

难度:中等。
标签:设计,哈希表,字符串,二分查找。

使用了哈希表+结构体存储数据,使用二分来查找数据。结果还是超时了,44/46用例没过。
开始没看完题,以为set的时间戳是任意的,不按照时间顺序严格递增,所以写了找第一个大于等于当前时间戳的戳。

超时代码:

class TimeMap {

    struct Item{
        string value;
        int time;
        Item(string v, int t){
            value = v;
            time = t;
        }
    };

    unordered_map<string, vector<Item>> data;

    // 找第一个大于等于now的时间戳
    int findLastIndex(vector<Item> items, int now){
        int n = items.size();
        int left = 0, right = n - 1, ans = n;
        while(left <= right){
            int mid = (left + right) / 2;
            if(items[mid].time == now)return mid;
            else if(items[mid].time > now){
                ans = mid;
                right = mid - 1;
            }
            else{
                left = mid + 1;
            }
        }
        return ans;
    }

public:
    /** Initialize your data structure here. */
    TimeMap() {

    }
    
    void set(string key, string value, int timestamp) {
        data[key].emplace_back(Item(value, timestamp));
    }
    
    string get(string key, int timestamp) {
        if(data[key].size() == 0)return "";
        if(data[key][0].time > timestamp)return "";
        int idx = findLastIndex(data[key], timestamp);
        if(idx != data[key].size() && data[key][idx].time == timestamp)return data[key][idx].value;
        else return data[key][idx - 1].value;
    }
};

/**
 * 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);
 */

优化!
将findLastIndex换成找最后一个小于等于now的时间戳。
将struct改为pair。
还是超时。

超时代码:

class TimeMap {

    unordered_map<string, vector<pair<int, string>>> data;
    // 找最后一个小于等于now的时间戳
    int findLastIndex(vector<pair<int, string>> items, int now){
        int n = items.size();
        int left = 0, right = n - 1, ans = -1;
        while(left <= right){
            int mid = (left + right) / 2;
            if(items[mid].first == now)return mid;
            else if(items[mid].first > now){
                right = mid - 1;
            }
            else{
                ans = mid;
                left = mid + 1;
            }
        }
        return ans;
    }

public:
    /** Initialize your data structure here. */
    TimeMap() {

    }
    
    void set(string key, string value, int timestamp) {
        data[key].emplace_back(pair{timestamp, value});
    }
    
    string get(string key, int timestamp) {
        if(data[key].size() == 0)return "";
        if(data[key][0].first > timestamp)return "";
        int idx = findLastIndex(data[key], timestamp);
        return data[key][idx].second;
    }
};

想不到了,看题解。
题解也是这个思路,为什么我超时了?
原因:函数的参数有vector<pair<int, string>>,传入使用的不是&,实参到形参的转换非常耗时。
因此加个引用就可以了。

去掉函数的正确解法:

class TimeMap {

    unordered_map<string, vector<pair<int, string>>> data;

public:
    /** Initialize your data structure here. */
    TimeMap() {

    }
    
    void set(string key, string value, int timestamp) {
        data[key].emplace_back(pair{timestamp, value});
    }
    
    string get(string key, int timestamp) {
        if(data[key].size() == 0)return "";
        if(data[key][0].first > timestamp)return "";
        int left = 0, right = data[key].size() - 1, ans = -1;
        while(left <= right){
            int mid = (left + right) / 2;
            if(data[key][mid].first == timestamp){
                ans = mid;
                break;
            }
            else if(data[key][mid].first > timestamp){
                right = mid - 1;
            }
            else{
                ans = mid;
                left = mid + 1;
            }
        }
        return data[key][ans].second;
    }
};

结果:
在这里插入图片描述

函数参数加引用的正确解法:

class TimeMap {

    unordered_map<string, vector<pair<int, string>>> data;
    // 找最后一个小于等于now的时间戳
    int findLastIndex(vector<pair<int, string>>& items, int now){
        int n = items.size();
        int left = 0, right = n - 1, ans = -1;
        while(left <= right){
            int mid = (left + right) / 2;
            if(items[mid].first == now)return mid;
            else if(items[mid].first > now){
                right = mid - 1;
            }
            else{
                ans = mid;
                left = mid + 1;
            }
        }
        return ans;
    }


public:
    /** Initialize your data structure here. */
    TimeMap() {

    }
    
    void set(string key, string value, int timestamp) {
        data[key].emplace_back(pair{timestamp, value});
    }
    
    string get(string key, int timestamp) {
        if(data[key].size() == 0)return "";
        if(data[key][0].first > timestamp)return "";
        int idx = findLastIndex(data[key], timestamp);
        return data[key][idx].second;
    }
};

结果:
在这里插入图片描述
对比两个的结果,函数调用的进栈出栈可能消耗了部分内存。

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值