LRU缓存机制&分割回文串

1 LRU缓存机制

Least Recently Used,最近最少使用法则,如果容器的容量为N,那么容器里面总是保存最近使用的N个数据

  设计实现LRU缓存机制,支持put操作,get操作(不存在就返回-1),要求时间复杂度为O(1);

思考:首先由时间复杂度O(1),可以想到我们可能需要使用数组以及哈希表;然后我们需要根据数据的使用频率来调整数据,在适当的时候删掉最不经常用的数据,那么我们可能就需要一个支持双向的容器(deque、list);
  我们可以通过取数据的同时,将数据移动到容器的头部,这样,使用频率最低的数据就自动排到了末尾;那么我们需要在数据的中间位置删除元素,而list可以在常数时间复杂度删除元素,因此我们选择list;
  由于list的查找时间复杂度O(N),所以,我们可以使用一个哈希表来存储对应的key,这样就实现了常数复杂度查找元素;而value我们存储在list里面,所以哈希表里面我们可以存储对应的迭代器,通过迭代器来访问对应的value;

最开始的思路,有一点问题:put的时候,如果容器已满,无法删除末尾元素在哈希表里面的键值

class LRU{
   
public:
    int N;
    list<int> ls;
    unordered_map<int ,list<int>::iterator> mp;
public:
    LRU(int n):N(n){
   };
    //插入
    void put(int key,int value){
   
        if(ls.size()==N){
   
            //删除最后一个节点
            mp.erase();//无法通过ls.back()来让mp删除对应的key
            ls.pop_back();
        }
        if(mp.count(key)){
   
            //如果之前的key已经存在,就将其value替换为新的value
            ls.erase(mp[key]);
        }
        auto node=make_pair(key,value);
        ls.push_front(node);
        mp[key]=ls.begin();
    }
    //删除
    int get(int key){
   
        if(!mp.count(key))
            return -1;
        int value=*mp[key];
        ls.erase(mp[key]);
        ls.push_front(value);
        mp[key]=ls.begin();
        return value;
    }
};

解决的方法是,在list里面存储key,以及value;这样就可以通过list里面的元素,得到其对应的键值key,从而就可以在哈希表里面删除对应的key

完整代码

/* LRU(Least Recently Used)缓存机制:支持get put 操作,总是保存最经常用的几个数据 */

#include<iostream>
#include<list>
#include<unordered_map>
using namespace std;

class LRU{
   
public:
    int N;
    list<pair<int,int>> ls;
    unordered_map<int ,list<pair<int,int>>::iterator> mp;
public:
    LRU(int n):N(n){
   };
    void put(int key,int value){
   
        if(ls.size()==N){
   
            //删除最后一个节点
            mp.erase(ls.back().first);
            ls.pop_back();
        }
        if(mp.count(key)){
   
            //如果之前的key已经存在,就将其value替换为新的value
            ls.erase(mp[key]);
        }
        auto node=make_pair(key,value);
        ls.push_front(node);
        mp[key]=ls.begin();
    }
    int get(int key){
   
        if(!mp.count(key))
            return -1;
        auto node=make_pair(key,(*mp[key]).second);
        ls.erase(mp[key]);
        ls.push_front(node);
        mp[key]=ls.begin();
        return node.second;
    }

};

int main(){
   
    LRU solu{
   4};
    solu.put(1,100);
    solu.put(2,200);
    solu.put(3,300);

    cout<<solu.get(2)<<endl;
    cout<<solu.get(20)<<endl;
    return 0;
}

2 分割回文串

#include<iostream>
#include<string>
#include<vector>
using namespace std;

class Solu{
   
private:
    vector<vector<string>> ans;
    vector<string> str;
public:
    //回溯
    void dfs(string& s,int left){
   
        if(left==s.length()){
   
            ans.push_back(str);
            return;
        }
        for(int i=left;i<s.length();++i){
   
            string tmp=s.substr(left,i-left+1);
            if(isPalinStr(tmp)){
   
                str.push_back(tmp);
                dfs(s,left+1);
                str.pop_back();
            }
        }
    }
    //判断字符串是否回文
    bool isPalinStr(string& s){
   
        int i=0,j=s.length()-1;
        while(i<=j){
   
            if(s[i]!=s[j])
                return false;
            i++;
            j--;
        }
        return true;
    }
    vector<vector<string>> ReturnPalindormString(string s){
   
        //返回s里面可以切割出的所有回文字符串方案
        dfs(s,0);
        return ans;
    };
};

int main(){
   
    string s="aab";
    Solu S;
    vector<vector<string>>&& ans=S.ReturnPalindormString(s);
    return 0;
}

原来,还可以使用动态规划,提前存储好子字符串是否是回文串!!


继续努力 ୧((〃•̀ꇴ•〃))૭⁺✧

刷题总结类 文章被收录于专栏

这里记录一些刷题时候的总结思考

全部评论

相关推荐

避坑恶心到我了大家好,今天我想跟大家聊聊我在成都千子成智能科技有限公司(以下简称千子成)的求职经历,希望能给大家一些参考。千子成的母公司是“同创主悦”,主要经营各种产品,比如菜刀、POS机、电话卡等等。听起来是不是有点像地推销售公司?没错,就是那种类型的公司。我当时刚毕业,急需一份临时工作,所以在BOSS上看到了千子成的招聘信息。他们承诺无责底薪5000元,还包住宿,这吸引了我。面试的时候,HR也说了同样的话,感觉挺靠谱的。于是,我满怀期待地等待结果。结果出来后,我通过了面试,第二天就收到了试岗通知。试岗的内容就是地推销售,公司划定一个区域,然后你就得见人就问,问店铺、问路人,一直问到他们有意向为止。如果他们有兴趣,你就得摇同事帮忙推动,促进成交。说说一天的工作安排吧。工作时间是从早上8:30到晚上18:30。早上7点有人叫你起床,收拾后去公司,然后唱歌跳舞(销售公司都这样),7:55早课(类似宣誓),8:05同事间联系销售话术,8:15分享销售技巧,8:30经理训话。9:20左右从公司下市场,公交、地铁、自行车自费。到了市场大概10点左右,开始地推工作。中午吃饭时间大约是12:00,公司附近的路边盖饭面馆店自费AA,吃饭时间大约40分钟左右。吃完饭后继续地推工作,没有所谓的固定中午午休时间。下午6点下班后返回公司,不能直接下班,需要与同事交流话术,经理讲话洗脑。正常情况下9点下班。整个上班的一天中,早上到公司就是站着的,到晚上下班前都是站着。每天步数2万步以上。公司员工没有自己的工位,百来号人挤在一个20平方米的空间里听经理洗脑。白天就在市场上奔波,公司的投入成本几乎只有租金和工资,没有中央空调。早上2小时,晚上加班2小时,纯蒸桑拿。没有任何福利,节假日也没有3倍工资之类的。偶尔会有冲的酸梅汤和西瓜什么的。公司的晋升路径也很有意思:新人—组长—领队—主管—副经理—经理。要求是业绩和团队人数,类似传销模式,把人留下来。新人不能加微信、不能吐槽公司、不能有负面情绪、不能谈恋爱、不能说累。在公司没有任何坐的地方,不能依墙而坐。早上吃早饭在公司外面的安全通道,未到上班时间还会让你吃快些不能磨蹭。总之就是想榨干你。复试的时候,带你的师傅会给你营造一个钱多事少离家近的工作氛围,吹嘘工资有多高、还能吹自己毕业于好大学。然后让你早点来公司、无偿加班、抓住你可能不会走的心思进一步压榨你。总之,大家在找工作的时候一定要擦亮眼睛,避免踩坑!———来自网友
qq乃乃好喝到咩噗茶:不要做没有专业门槛的工作
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务