[leetcode]LRU Cache

双链表+map 实现。所有数据存在链表里,map里存key到Node*的映射。注意当删除时除了要从链表尾部删除节点外,还要map.erase(it)。Node里也要有key,因为为了删除时方便找到it。

#include <map>
using namespace std;

class Node {
public:
    int key;
    int val;
    Node* prev;
    Node* next;
    Node(int _key, int _val) {
        key = _key;
        val = _val;
        prev = NULL;
        next = NULL;
    }
};

class LRUCache{
public:
    LRUCache(int _capacity) {
        capacity = _capacity;
        head = new Node(-1, -1);
        tail = new Node(-1, -1);
        head->next = tail;
        tail->prev = head;
        mp.clear();
        size = 0;
    }
    
    int get(int key) {
        if (mp.find(key) == mp.end()) { // not found
            return -1;
        }
        else { // found
            Node* cur = mp.find(key)->second;
            cur->next->prev = cur->prev;
            cur->prev->next = cur->next;
            moveToFirst(cur);
            return cur->val;
        }
    }
    
    void set(int key, int value) {
        if (capacity == 0) return;
        if (mp.find(key) == mp.end()) { // not found
            if (size >= capacity) {
                // remove last one
                Node* deltmp = tail->prev;
                deltmp->prev->next = tail;
                tail->prev = deltmp->prev;
                unordered_map<int, Node*>::iterator it = mp.find(deltmp->key);
                mp.erase(it);
                delete deltmp;                
                size--;
            }
            Node* addtmp = new Node(key, value);
            moveToFirst(addtmp);
            mp[key] = addtmp;
            size++;
        }
        else { // found
            Node* cur = mp.find(key)->second;
            cur->val = value;
            cur->next->prev = cur->prev;
            cur->prev->next = cur->next;
            moveToFirst(cur);
        }
    }
    
private:
    unordered_map<int, Node*> mp;
    int capacity = 0;
    int size = 0;
    Node* head = NULL;
    Node* tail = NULL;
    
    void moveToFirst(Node* cur) {
        cur->next = head->next;
        cur->prev = cur->next->prev;
        head->next = cur;
        cur->next->prev = cur;
    }
};

Python3,hashmap+双链表

要注意moveToHead的时候,要先将节点从前后摘除,在放到首位

class LRUCache:

    def __init__(self, capacity: int):
        self.hashmap = {}
        self.capacity = capacity
        self.dummyHead = Node(0, 0)
        self.dummyTail = Node(0, 0)
        self.dummyHead.next = self.dummyTail
        self.dummyTail.prev = self.dummyHead

    def get(self, key: int) -> int:
        if key not in self.hashmap:
            return -1
        self.moveToHead(key)

        return self.hashmap[key].val

    def moveToHead(self, key):
        node = self.hashmap[key]
        
        nodeNext = node.next
        nodePrev = node.prev
        nodeNext.prev = nodePrev
        nodePrev.next = nodeNext

        headNext = self.dummyHead.next
        self.dummyHead.next = node
        node.prev = self.dummyHead
        node.next = headNext
        headNext.prev = node

    def put(self, key: int, value: int) -> None:
        if key in self.hashmap:
            self.hashmap[key].val = value
            self.moveToHead(key)
        else:
            self.hashmap[key] = Node(key, value)
            node = self.hashmap[key]
            node.next = self.dummyHead.next
            self.dummyHead.next.prev = node
            node.prev = self.dummyHead
            self.dummyHead.next = node

        # if full, remove tail
        if len(self.hashmap) > self.capacity:
            tail = self.dummyTail.prev
            prev = tail.prev
            
            prev.next = self.dummyTail
            self.dummyTail.prev = prev

            del self.hashmap[tail.key]
        

class Node:

    def __init__(self, key:int, val: int):
        self.key = key
        self.val = val
        self.next = None
        self.prev = None


# Your LRUCache object will be instantiated and called as such:
# obj = LRUCache(capacity)
# param_1 = obj.get(key)
# obj.put(key,value)

  

posted @ 2014-01-09 13:37  阿牧遥  阅读(183)  评论(0编辑  收藏  举报