[Leetcode] LRU Cache

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

get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.
set(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.

直到做到这道题时,我才知道了原来Clock算法不等于LRU算法,Clock算法只是一种近似的LRU算法,但两者的调度结果不完全一样。一上来我先想的是Clock算法,然后就一直WA!

LRU算法就是维护一个链表,最新的结果放在链表的最后面,所以每次只要替换链表的头结点就行了,下面是代码:

 1 class LRUCache{
 2 public:
 3     struct Node {
 4         int key;
 5         int val;
 6         Node *next;
 7         Node() : key(-1), val(-1) {}
 8         Node(int k, int v) : key(k), val(v) {}
 9     };
10     
11     Node *cache;
12     Node *tail;
13     int capacity;
14     int size;
15     
16     LRUCache(int capacity) {
17         this->capacity = capacity;
18         size = 0;
19         cache = new Node();
20         tail = cache;
21     }
22     
23     int get(int key) {
24         Node *pos = cache;
25         int val;
26         while (pos != tail && pos->next != NULL) {
27             if (pos->next->key == key) {
28                 val = pos->next->val;
29                 tail->next = pos->next;
30                 pos->next = pos->next->next;
31                 tail = tail->next;
32                 tail->next = NULL;
33                 return val;
34             }
35             pos = pos->next;
36         }
37         return -1;
38     }
39     
40     void set(int key, int value) {
41         Node *pos = cache;
42         while (pos != tail && pos->next != NULL) {
43             if (pos->next->key == key) {
44                 pos->next->val = value;
45                 tail->next = pos->next;
46                 pos->next = pos->next->next;
47                 tail = tail->next;
48                 tail->next = NULL;
49                 return;
50             }
51             pos = pos->next;
52         }
53         if (size < capacity) {
54             tail->next = new Node(key, value);
55             tail = tail->next;
56             ++size;
57         } else {
58             cache->next->key = key;
59             cache->next->val = value;
60             tail->next = cache->next;
61             cache->next = cache->next->next;
62             tail = tail->next;
63             tail->next = NULL;
64         }
65     }
66 };

可以使用map来加速查找的过程,使用STL里的list也可以使代码精简不少。

 1 class LRUCache{
 2 private:
 3     list<pair<int, int>> mlist;
 4     unordered_map<int, list<pair<int, int>>::iterator> mmap;
 5     int mcapacity;
 6     
 7 public:
 8     LRUCache(int capacity) {
 9         mlist.clear();
10         mmap.clear();
11         mcapacity = capacity;
12     }
13     
14     int get(int key) {
15         if (mmap.find(key) != mmap.end()) {
16             pair<int, int> tmp = *(mmap[key]);
17             mlist.erase(mmap[key]);
18             mlist.push_front(tmp);
19             mmap[key] = mlist.begin();
20             return mlist.front().second;
21         } else { 
22             return -1;
23         }
24     }
25     
26     void set(int key, int value) {
27         if (mmap.find(key) != mmap.end()) {
28             mlist.erase(mmap[key]);
29             mlist.push_front(make_pair(key, value));
30         } else {
31             if (mlist.size() == mcapacity) {
32                 mmap.erase(key);
33                 mlist.pop_back();
34             }
35             mlist.push_front(make_pair(key, value));
36         }
37         mmap[key] = mlist.begin();
38     }
39 };

 

虽然Clock算法不合题意,代码还是帖上来吧,下面是Clock算法:

 1 class LRUCache{
 2 public:
 3     struct node {
 4         int key;
 5         int value;
 6         bool tag;
 7         node() {
 8             key = -1;
 9             value = -1;
10             tag = false;
11         }
12     };
13     
14     node *cache;
15     int size;
16     int pos;
17     
18     LRUCache(int capacity) {
19         pos = 0;
20         size = capacity;
21         cache = new node[capacity];
22     }
23     
24     int get(int key) {
25         for (int i = 0; i < size; ++i) {
26             if (cache[i].key == key) {
27                 cache[i].tag = true;
28                 return cache[i].value;
29             }
30         }
31         return -1;
32     }
33     
34     void set(int key, int value) {
35         for (int i = 0; i < size; ++i) {
36             if (cache[i].key == key) {
37                 cache[i].tag = true;
38                 cache[i].value = value;
39                 return;
40             }
41         }
42         while(cache[pos].tag) {
43             cache[pos].tag = false;
44             ++pos;
45             pos %= size;
46         }
47         cache[pos].key = key;
48         cache[pos].value = value;
49         cache[pos].tag = true;
50         ++pos;
51         pos %= size;
52     }
53 };

 

 

 

posted @ 2014-04-08 13:34  Eason Liu  阅读(287)  评论(0编辑  收藏  举报