zoukankan      html  css  js  c++  java
  • 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 };
  • 相关阅读:
    Wayland中的跨进程过程调用浅析
    设计模式总结
    C语言---整型字符串转换
    抽象工厂模式
    SVNclient安装与使用
    [置顶] MyEclipse下安装插件方法(properties文件编辑器Propedit为例)
    脑筋急转弯的歧义性
    脑筋急转弯的歧义性
    从和式积分到定积分
    从和式积分到定积分
  • 原文地址:https://www.cnblogs.com/yeek/p/3574868.html
Copyright © 2011-2022 走看看