leetcode-145-LRU cache

来源:互联网 发布:前端框架 知乎 编辑:程序博客网 时间:2024/06/02 05:10

问题

题目:[leetcode-145]

思路

参考了[O(1) unordered_map + list + splice]
参考者代码的思路非常清晰。
首先,插入和获取的时间复杂度在O(1),不能用deque去实现。否则无法到达常数。采用链表,插入,删除的时间复杂度都是o(1)。需要双向链表,可以自己实现。可以使用stl::list. 由于链表不支持随机访问,所以,做一次哈希。

代码

class LRUCache {public:    LRUCache(int capacity) : cap_(capacity) {}    int get(int key) {        if( cache_map_.find(key) == cache_map_.end() ) return -1;        else{            int val = cache_map_[key]->val;            cache_list_.splice( cache_list_.begin(), cache_list_, cache_map_[key] );            return val;        }    }    void put(int key, int value) {        if( cache_map_.find(key) != cache_map_.end() ){            cache_map_[key]->val = value;            cache_list_.splice(cache_list_.begin(), cache_list_, cache_map_[key]);        }else{            element e(key, value);            if(cache_list_.size() < cap_){                cache_list_.push_front(e);                cache_map_[key] = cache_list_.begin();            }else{                cache_map_.erase(cache_list_.back().key);                cache_list_.pop_back();                cache_list_.push_front(e);                cache_map_[key] = cache_list_.begin();            }        }    }private:    struct element{        int key;        int val;        element(): key(0),val(0){}        element(int k, int v) : key(k), val(v){}    };    std::list<element> cache_list_;    std::unordered_map< int, std::list<element>::iterator > cache_map_;    int cap_;};/** * Your LRUCache object will be instantiated and called as such: * LRUCache obj = new LRUCache(capacity); * int param_1 = obj.get(key); * obj.put(key,value); */

代码1

自己实现了循环双链表,注意pop_back的时候,别忘了从哈希表删除。

class LRUCache {public:    LRUCache(int capacity) : cap_(capacity), size_(0) {        head_ = tail_ = new Node();        assert(head_);        assert(cap_);    }    int get(int key) {        std::cout << "get: " << key << std::endl;        if( cache_map_.find(key) == cache_map_.end() ) return -1;        else{            CacheList p = cache_map_[key];            move_to_head(p);            return p->val;        }    }    void put(int key, int value) {        std::cout << "put: " << key << "," << value << std::endl;        if( cache_map_.find(key) != cache_map_.end() ){            CacheList p = cache_map_[key];            p->val = value;            move_to_head(p);        }else{            CacheList p = new Node();            p->key = key;            p->val = value;            ++size_;            if(size_ <= cap_){                insert_head(p);                cache_map_[key] = p;            }else{                size_ = cap_;                cache_map_.erase(tail_->key);                delete_tail();                insert_head(p);                cache_map_[key] = p;            }        }    }    ~LRUCache() { delete head_; }private:    struct Node {        int key;        int val;        Node* next;        Node* prev;        Node() { memset(this, 0, sizeof(Node));}    };    typedef Node* CacheList;    CacheList head_;    CacheList tail_;    int cap_;    int size_;    unordered_map<int, CacheList> cache_map_;private:        void move_to_head(CacheList p){        if( head_ == tail_ ) return ;        if( head_->next == p ) return ;        else{            if(p == tail_){                tail_ = tail_->prev;                tail_->next = NULL;            }            else{                CacheList pre = p->prev;                CacheList nex = p->next;                pre->next = nex;                nex->prev = pre;            }            insert_head(p);        }    }    void insert_head(CacheList p){        CacheList q = head_->next;        p->next = q;        p->prev = head_;        head_->next = p;        if(q) q->prev = p;        else tail_ = p;    }    void delete_tail(){        if(head_ == tail_) return;        CacheList p = tail_;        tail_ = tail_->prev;        tail_->next = NULL;        delete p;    }};

代码2

bug在于,要区别两类迭代器。不是一回事!

class LRUCache {public:    LRUCache(int capacity) {        cap_ = capacity;    }    int get(int key) {        if( cache_map_.find(key) == cache_map_.end() ) return -1;        else{            Iter it = cache_map_[key];            // move to head            cache_list_.splice( cache_list_.begin(), cache_list_, it );            // return value            return it->second;        }    }    void put(int key, int value) {        if( cache_map_.find(key) != cache_map_.end() ){            Iter it = cache_map_[key];            // update the value            it->second = value;            // move to head            cache_list_.splice( cache_list_.begin(), cache_list_, it );        }        else{            if( cache_list_.size() == cap_ ){                cache_map_.erase( cache_list_.back().first );                cache_list_.pop_back();            }            Node node(key, value);            cache_list_.push_front(node);            cache_map_[key] = cache_list_.begin();        }    }private:    typedef pair<int, int> Node;    typedef list<Node>::iterator Iter;    list<Node> cache_list_;    unordered_map<int, Iter> cache_map_;    int cap_;};
原创粉丝点击