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.

Solution From 水印人生:

class LRUCache {
    class ListNode {
    public:
        ListNode(int v, int k) : val(v), key(k) {
            prev = NULL;
            next = NULL;
        }
        int val;
        int key;
        ListNode *next;
        ListNode *prev;
    };
public:    
    int c;
    ListNode *head;
    ListNode *tail;
    map<int, ListNode *> key_node_map;
    
    LRUCache(int capacity) : c(capacity) {
        head = NULL;
        tail = NULL;
    }
    
    int get(int key) {
        if (key_node_map.find(key) == key_node_map.end())
            return -1;
        else {
            int temp = key_node_map[key]->val;
            set(key, temp);
            return temp;
        }
    }
    void set(int key, int value) {
        if (key_node_map.find(key) == key_node_map.end()) {
           ListNode *n = new ListNode(value, key);
           key_node_map[key] = n;
           n->next = head;
           n->prev = NULL;
           if (head!=NULL) head->prev = n;
           if (!tail) tail = n;
           head = n;
           if (key_node_map.size() > c) {
               key_node_map.erase(tail->key);
               ListNode *temp = tail->prev;
               delete tail;
               if (temp) {
                   temp->next = NULL;
                   tail = temp;
               } else {
                   tail = NULL;
               }
           }
        } else {
            ListNode *n = key_node_map[key];
            n->val = value;
            if (n->prev != NULL)
                n->prev->next = n->next;
            if (n->next != NULL) 
                n->next->prev = n->prev ? n->prev : n;
            if (n->next == NULL)
                tail = n->prev ? n->prev : n;
            if (n->prev != NULL) {
                n->next = head;
                head->prev = n;
                n->prev = NULL;
                head = n;
            }
        }
    }
};

 Solution from 水中鱼:

 1 class LRUCache{
 2 public:
 3     struct CacheEntry
 4     {
 5     public:
 6         int key;
 7         int value;
 8         CacheEntry(int k, int v) :key(k), value(v) {}
 9     };
10 
11     LRUCache(int capacity) {
12         m_capacity = capacity;
13     }
14 
15     int get(int key) {
16         if (m_map.find(key) == m_map.end())
17             return -1;
18 
19         MoveToHead(key);
20         return m_map[key]->value;
21     }
22 
23     void set(int key, int value) {
24         if (m_map.find(key) == m_map.end())
25         {
26             CacheEntry newItem(key, value);
27             if (m_LRU_cache.size() >= m_capacity)
28             {
29                 //remove from tail
30                 m_map.erase(m_LRU_cache.back().key);
31                 m_LRU_cache.pop_back();                
32             }
33 
34             // insert in head.
35             m_LRU_cache.push_front(newItem);
36             m_map[key] = m_LRU_cache.begin();
37             return;
38         }
39 
40         m_map[key]->value = value;
41         MoveToHead(key);
42     }
43 
44 private:
45     unordered_map<int, list<CacheEntry>::iterator> m_map;
46     list<CacheEntry> m_LRU_cache;
47     int m_capacity;
48 
49     void MoveToHead(int key) 
50     {
51         //Move key from current location to head
52         auto updateEntry = *m_map[key];
53         m_LRU_cache.erase(m_map[key]);
54         m_LRU_cache.push_front(updateEntry);
55         m_map[key] = m_LRU_cache.begin();
56     }
57 
58 };

 

posted @ 2014-03-01 11:38  andyqee  阅读(152)  评论(0编辑  收藏  举报