力扣146. LRU 缓存(STL实现)

核心思路是有两个数据结构,一个哈希表和一个双向链表。双向链表用来实现一个队列,队头元素最近被使用,队尾元素最久没被使用;哈希表用来记录key与key相应的节点在链表中的指针。

1.面试场景要的应该是自己写结构体来实现双向链表,写的时候注意位置交换时指针的操作顺序

2.注意每次操作要同时维护哈希表和链表

3.STL中的list已经是双端队列,可以前插后插,也可以插在中间

4.list中需要存储key的值,方便通过list队尾元素来删除哈希表中相应的键值对

class LRUCache {
public:
    list<pair<int, int>> deque; //这里不能直接使用deque,因为deque使用erase(it)会导致it之后的迭代器也失效
    unordered_map<int, list<pair<int, int>>::iterator> table;

    int capacity;
    LRUCache(int capacity) {
        this -> capacity = capacity;
    }
    
    int get(int key) {
        auto it = table.find(key);
        if (it == table.end()) return -1;
        int v = it -> second -> second;
        deque.erase(it -> second);
        deque.push_front(make_pair(key, v));
        table[key] = deque.begin();
        return v;
    }
    
    void put(int key, int value) {
        auto it = table.find(key);
        if (it == table.end() && deque.size() == capacity) { //容量不够时删除队尾元素
            table.erase(deque.back().first); //需要在哈希表中也删除队尾元素项
            deque.pop_back();
        } else if (it != table.end()){
            deque.erase(it -> second);
        }
        deque.push_front(make_pair(key, value));
        table[key] = deque.begin();
    }
};

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

 使用list的splice函数快速移动迭代器到头部

 1 class LRUCache {
 2 public:
 3     int capacity;
 4     typedef pair<int, int> pii;
 5     list<pii> cache;
 6     unordered_map<int, list<pii>::iterator> m;
 7     LRUCache(int capacity) {
 8         this -> capacity = capacity;
 9     }
10     
11     int get(int key) {
12         if (m.count(key)) {
13             int value = m[key] -> second;
14             cache.splice(cache.begin(), cache, m[key]);
15             return value;
16         }
17         return -1;
18     }
19     
20     void put(int key, int value) {
21         if (m.count(key)) {
22             m[key] -> second = value;
23             cache.splice(cache.begin(), cache, m[key]);
24         } else {
25             if (cache.size() == capacity) {
26                 m.erase(cache.back().first);
27                 cache.pop_back();
28                 cache.push_front(make_pair(key, value));
29                 m[key] = cache.begin();
30             } else {
31                 cache.push_front(make_pair(key, value));
32                 m[key] = cache.begin();
33             }
34         }
35     }
36 };
37 
38 /**
39  * Your LRUCache object will be instantiated and called as such:
40  * LRUCache* obj = new LRUCache(capacity);
41  * int param_1 = obj->get(key);
42  * obj->put(key,value);
43  */

 

posted on 2025-02-28 12:24  Coder何  阅读(45)  评论(0)    收藏  举报