力扣146. LRU 缓存
① 刚开始的思路是哈希表+一个环形缓冲区,但是看到条件中可以重复,那这样可就麻烦了,另外,真的没有想到哈希表中存地址,另外list中既要保存key,也要保存value,按理说只有value就可以,但是要考虑一个点,就是size达到capacity的时候,要通过key才能找到删除哈希表中的哪一个;
② c++的链表要手搓。。。
③ 有一个优化点,就是反复利用已经存在的listnode,将要淘汰的node直接挪到前面,改变key,这样就不用重新申请内存和释放内存了
题目:【https://leetcode.cn/problems/lru-cache/?envType=study-plan-v2&envId=top-interview-150】
1 class DListNode { 2 public: 3 int key; 4 int value; 5 DListNode* prev; 6 DListNode* next; 7 DListNode(int _key) 8 : key(_key) 9 , prev(NULL) 10 , next(NULL) 11 {} 12 DListNode(int _key, int _value) 13 : key(_key) 14 , value(_value) 15 , prev(NULL) 16 , next(NULL) 17 {} 18 }; 19 20 class LRUCache { 21 public: 22 LRUCache(int capacity) 23 : m_size(0) 24 , m_capacity(capacity) 25 , m_head(new DListNode(0)) 26 , m_tail(new DListNode(0)) 27 { 28 m_head->next = m_tail; 29 m_tail->prev = m_head; 30 } 31 32 int get(int key) { 33 if (m_keys.count(key) <= 0) 34 return -1; 35 36 DListNode* t = m_keys[key]; 37 removeListNode(t->prev, t->next); 38 insertListNode(m_head, m_head->next, t); 39 return t->value; 40 } 41 42 void put(int key, int value) { 43 DListNode* tn = m_keys[key]; 44 if (NULL == tn) { 45 if (m_size >= m_capacity) { 46 tn = m_tail->prev; 47 m_keys.erase(tn->key); 48 tn->key = key; 49 removeListNode(tn->prev, tn->next); 50 } else { 51 tn = new DListNode(key); 52 m_size++; 53 } 54 } else { 55 if (m_head->next == tn) { 56 tn->value = value; 57 return ; 58 } 59 removeListNode(tn->prev, tn->next); 60 } 61 62 insertListNode(m_head, m_head->next, tn); 63 64 tn->value = value; 65 66 m_keys[key] = tn; 67 } 68 69 private: 70 void insertListNode(DListNode* prev, DListNode* next, DListNode* node) 71 { 72 node->next = next; 73 node->prev = prev; 74 prev->next = node; 75 next->prev = node; 76 } 77 void removeListNode(DListNode* prev, DListNode* next) 78 { 79 prev->next = next; 80 next->prev = prev; 81 } 82 83 private: 84 unordered_map<int, DListNode*> m_keys; 85 int m_size; 86 int m_capacity; 87 DListNode* m_head; 88 DListNode* m_tail; 89 }; 90 91 /** 92 * Your LRUCache object will be instantiated and called as such: 93 * LRUCache* obj = new LRUCache(capacity); 94 * int param_1 = obj->get(key); 95 * obj->put(key,value); 96 */