Leetcode 146. LRU Cache

Problem:

Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and put.

get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.
put(key, value) - Set or insert the value if the key is not already present. When the cache reached its capacity, it should invalidate the least recently used item before inserting a new item.

Follow up:
Could you do both operations in O(1) time complexity?

Example:

LRUCache cache = new LRUCache( 2 /* capacity */ );

cache.put(1, 1);
cache.put(2, 2);
cache.get(1);       // returns 1
cache.put(3, 3);    // evicts key 2
cache.get(2);       // returns -1 (not found)
cache.put(4, 4);    // evicts key 1
cache.get(1);       // returns -1 (not found)
cache.get(3);       // returns 3
cache.get(4);       // returns 4

 

Solution:

  笔试高频题,我在今年笔试中已经两次碰见该题了。这道题是链表和哈希表的结合。对于这道题有几个基础知识必须了解,一个是链表的迭代器失效问题,和vector不同,链表的删除操作只会使迭代器指向的当前节点失效。第二个是第十行的splice函数,它的原型是void splice (iterator position, list& x, iterator i),其作用是仅将链表x中的i指向的一个节点拼接到position的位置。接下来就很简单了,put函数通过哈希表找到key所在链表中的迭代器,将其删除,然后在链表开头添加新的pair,并将哈希表重新赋值。如果超出限制范围,则在链表和哈希表中删除最后一个节点。对于get函数,通过哈希表找到结果,然后通过splice函数将该节点移动到链表开头。

Code:

 

 1 class LRUCache {
 2 public:
 3     LRUCache(int capacity) {
 4         limit = capacity;
 5     }
 6     
 7     int get(int key) {
 8         auto it = um.find(key);
 9         if (it == um.end()) return -1;
10         l.splice(l.begin(), l, it->second);
11         return it->second->second;
12     }
13     
14     void put(int key, int value) {
15         auto iter = um.find(key);
16         if(iter != um.end()) 
17             l.erase(iter->second);
18         l.push_front(make_pair(key,value));
19         um[key] = l.begin();
20         if(um.size() > limit){
21             um.erase(l.rbegin()->first);
22             l.pop_back();
23         }
24     }
25 private:
26     int limit;
27     list<pair<int, int>> l;
28     unordered_map<int, list<pair<int, int>>::iterator> um;
29 };
30 
31 /**
32  * Your LRUCache object will be instantiated and called as such:
33  * LRUCache obj = new LRUCache(capacity);
34  * int param_1 = obj.get(key);
35  * obj.put(key,value);
36  */

 

posted on 2019-01-13 14:53  周浩炜  阅读(142)  评论(0编辑  收藏  举报

导航