[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 };

 

 

 

你可能感兴趣的:(LeetCode)