Leetcode--LRU Cache

http://oj.leetcode.com/problems/lru-cache/html

 

參考了 這篇文章,是用雙向鏈表和unordered_map來實現的,難點在於複雜的指針操做,以及每次get,set以後都要考慮map是否要改變,還有,要同步更新size,這也容易遺忘
最後,我從中抽象出一個moveToHead的函數,簡化了代碼
 
原本想用單鏈表實現的,到中途發現彷佛不行
過後的思考:也許有單獨的不存儲數據的頭結點和尾節點會使得真正操做簡單一點,能夠避免考慮不少邊界狀況,NULL指針問題
 
//seems that single linked list is not enough
#include <cstdio>
#include <cstdlib>
#include <unordered_map>
using namespace std;
class Node{
public:
    int key;
    int value;
    Node *next;
    Node *prev;
    Node(int k, int v, Node* n, Node *pre):key(k),value(v),next(n), prev(pre){}
};
class LRUCache{
public:
    LRUCache(int capacity) {
        if(capacity < 0){
            printf("error");
            exit(-1);
        }
        _head = _tail = NULL;
        _size = 0;
        _cap = capacity;
    }
    ~LRUCache(){
        if(_head == NULL) return;
        Node *p = _head, *q = _head->next;
        while(q){
            delete p;
            p = q;
            q = q->next;
        }
        delete p;
    }
    int get(int key) {
        auto it = _map.find(key);
        if(it == _map.end()){
            return -1;
        } else {
            moveToHead(it->second);
            return it->second->value;
        }
    }
    
    void set(int key, int value) {
        if(_cap == 0) return;
        if(_cap == 1){
            if(_size == 1){
                _map.erase(_head->key);
                _map[key] = _head;
                _head->key = key;
                _head->value = value;
                return;
            } else {//_size==0
                _head = _tail = new Node(key,value,NULL,NULL);
                _map[key] = _head;
                _size++;
                return;
            }
        }
        //_cap >= 2
        auto it = _map.find(key);
        if(it == _map.end()){
            if(_size < _cap){
                Node *p = new Node(key,value,_head, NULL);
                if(_head == NULL){
                    _head = _tail = p;
                    _map[key] = _head;
                    _size++;
                    return;
                }
                _head->prev = p;
                _head = p;
                _map[key] = p;
                _size++;
            } else {//_size >= _cap >= 0, actually, we always ensure that _cap >= _size, so _size must equal to _cap
                //_size == _cap >= 2
                Node *p = _tail;
                _map.erase(_tail->key);
                p->key = key;
                p->value = value;
                
                _map[key] = p;
                moveToHead(p);
            }
        } else {
            it->second->value = value;
            moveToHead(it->second);
        }
    }
    void moveToHead(Node* p){
        if(p==_head) return;
        p->prev->next = p->next;
        if(p == _tail){
            _tail = p->prev;
        } else {
            p->next->prev = p->prev;
        }
        p->next = _head;
        p->prev = NULL;
        _head->prev = p;
        _head = p;
    }
private:
    unordered_map<int,Node*> _map;
    Node *_head, *_tail;
    int _size;
    int _cap;
};

編譯要指定C++11(固然,你還要提供一個main函數才行),對於g++來講,添加 -std=c++11c++

相關文章
相關標籤/搜索