• [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 };
  • 相关阅读:
    《飞得更高孙正义传》成为亚洲首富肯定有原因
    AutoController通用自动增删查改
    Silverlight学习笔记第一季(3)扯扯ComboBox
    Silverlight学习笔记第一季(1)DataGrid
    菜鸟混社区之如何看待社区的口水战?
    局部化页面和效率CMS实践系列总结
    图片猜成语(思维@娱乐)
    接口+泛型强大的Repository
    Silverlight学习笔记第一季(2)Listbox横向绑定数据
    poj 2954 Triangle (pick 定理 的应用 )
  • 原文地址:https://www.cnblogs.com/easonliu/p/3651802.html
Copyright © 2020-2023  润新知