首页 > 其他分享 >LeetCode-146-LRU缓存

LeetCode-146-LRU缓存

时间:2023-07-01 19:57:32浏览次数:47  
标签:146 map capacity int list find LRU key LeetCode

146题:LRU缓存

题目

请你设计并实现一个满足  LRU (最近最少使用) 缓存 约束的数据结构。
实现 LRUCache 类:
LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存
int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 。
void put(int key, int value) 如果关键字 key 已经存在,则变更其数据值 value ;如果不存在,则向缓存中插入该组 key-value 。如果插入操作导致关键字数量超过 capacity ,则应该 逐出 最久未使用的关键字。
函数 getput 必须以 O(1) 的平均时间复杂度运行。

问题简述

我们需要在O(1)的平均复杂度内得到对应的值,所以我们需要利用哈希表来存储(也就是std::unordered_map)。同时,删除也需要我们有O(1)的时间复杂度,所以我们需要利用双向链表存储键值对。
这里我们需要用到链表拼接函数splice(),表示该节点刚刚用过,然后移动到链表头部。

void splice( const_iterator pos, list& other, const_iterator it );

这个函数声明表示it指向的节点移动到otherpos指向的节点。

template< class... Args >
void emplace_front( Args&&... args );

可以看见,emplace_front()是一个变长函数模板,所以我们可以直接利用该函数插入一个std::pair<int,int>

代码

class LRUCache {
    using MAP_ITER = std::list<std::pair<int,int>>::iterator;
public:

    LRUCache(int capacity): capacity_(capacity) {

    }
     
    int get(int key) {
         auto find_key = lru_map.find(key);
         if(find_key==lru_map.cend())
            return -1;
         map_list.splice(map_list.cbegin(), map_list, find_key->second);
         return find_key->second->second;
    }
    
    void put(int key, int value) {
        auto find_key = lru_map.find(key);
        if(find_key!=lru_map.cend())
        {
            find_key->second->second = value;
            map_list.splice(map_list.cbegin(), map_list, find_key->second);
            return;
        }
        if(map_list.size()>=capacity_)
        {
            std::pair<int,int> pair_back = map_list.back();
            lru_map.erase(pair_back.first);
            map_list.pop_back();
        }
        map_list.emplace_front(key, value);
        lru_map[key] = map_list.begin();

    }
private:
    int capacity_;
    std::list<std::pair<int,int>> map_list;
    std::unordered_map<int, MAP_ITER> lru_map;
};

/**
 * Your LRUCache object will be instantiated and called as such:
 * LRUCache* obj = new LRUCache(capacity);
 * int param_1 = obj->get(key);
 * obj->put(key,value);
 */

这里的get()函数思路很简单,首先判断哈希表里面有没有对应的key,如果找不到直接返回-1。如果找到了,由于这个key值刚刚用过,所以我们需要利用splice()函数将该节点置前,表示这个key值刚刚用过。
put()函数同样先查找有没有对应的key值,如果有,需要更新对应的value值(find_key->second->second=value)并将该节点置前。接着判断是否已经越界。如果越界,需要删除对应的哈希值并弹出链表的尾部值。接着,我们利用emplace_back()插入新的键值对,并更新哈希表的值。

标签:146,map,capacity,int,list,find,LRU,key,LeetCode
From: https://www.cnblogs.com/wyfc4/p/17519822.html

相关文章

  • [刷题记录Day1]Leetcode列表专题
    No.1题目二分查找思路要素:原数组升序排列清楚地定义左右边界优化空间:数组有序,通过第0元素和最后元素,可以避免查找不在数组范围内的target代码publicstaticintsearch(int[]nums,inttarget){//避免target小于nums[0],大于nums[nums.length-1]时参与运算......
  • LRU缓存机制
    LRU缓存题目链接LRU,即Least-Recently-Used。是一种高速缓存替换策略,是一种缓存机制。主要是利用局部性原理。局部性原理分两种,空间局部性和时间局部性。在一个具有良好时间局部性的程序中,被引用过一次的内存位置很可能在不远的将来再被多次应用。在一个具有良好空间局部性......
  • 【leetcode】【234】【回文链表】
    c++第一个方法#include<algorithm>#include<iostream>#include<memory>#include<vector>//Definitionforsingly-linkedlist.structListNode{intval;ListNode*next;ListNode():val(0),next(nullptr){}Li......
  • [刷题记录Day3]Leetcode链表专题
    #ListNodedefinitionpublicclassListNode{//结点的值intval;//下一个结点ListNodenext;//节点的构造函数(无参)publicListNode(){}//节点的构造函数(有一个参数)publicListNode(intval){this.val=val;......
  • 【leetcode】【206】【反转链表】
    c++第一个方法#include<algorithm>#include<iostream>#include<memory>#include<vector>//Definitionforsingly-linkedlist.structListNode{intval;ListNode*next;ListNode():val(0),next(nullptr){}Li......
  • 【leetcode】【83】【移除链表元素】
    c++第一个方法#include<algorithm>#include<iostream>#include<memory>#include<vector>//Definitionforsingly-linkedlist.structListNode{intval;ListNode*next;ListNode():val(0),next(nullptr){}Li......
  • LeetCode 142. 环形链表 II
    /***Definitionforsingly-linkedlist.*structListNode{*intval;*ListNode*next;*ListNode(intx):val(x),next(NULL){}*};*/classSolution{public:ListNode*detectCycle(ListNode*head){if(!head)return......
  • LeetCode算法题---最长回文子串、N 字形变换(四)
    5.最长回文子串题目要求:给你一个字符串 s,找到 s 中最长的回文子串。如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。示例1: 输入:s="babad"输出:"bab"解释:"aba"同样是符合题意的答案。 示例2:输入:s="cbbd"输出:"bb"提示:1<=s.length<=1000s仅由数字......
  • [刷题记录]Leetcode列表专题
    No.1题目Leetcodelink思路数组本身是非降序,即最小值和最大值在数组的两端非降序数组每个元素平方后,最大值在两端,最小值在中部双指针比较数组两端最大值的大小,提取出最大的。移动双指针,然后得到次大,次次大,逐步得到结果注意left==right是有意义的,即待处理数组只有一个元素,......
  • 四种语言刷算法之LRU 缓存
    力扣146. LRU缓存1、Ctypedefstruct{intkey;intval;UT_hash_handlehh;}LRUCache;LRUCache*usr=NULL;intsize=0;LRUCache*lRUCacheCreate(intcapacity){size=capacity;returnusr;}intlRUCacheGet(LRUCache*obj,intke......