LeetCode 146. LRU Cache

高频题,需要用unordered_map和list,做到O(1)。unordered_map: key->iterator,而list的元素是pair(key,value) 是有好处的,这样我们就不用另外一个hashtable来记录 key->val。

至于为何要将key和value的pair作为list的元素,而不是仅仅用value作为list的元素,是因为在超过cap的时候,我们可以用 l.back().first O(1) 得到key然后从unordered_map里删除key与iterator的对应关系。

需要注意的一点是,list用了splice改变了节点的位置,但是iterator并不会失效,这也代表unordered_map不需要进行更新。(可以把iterator当成指针方便理解)

class LRUCache {
public:
    int cap;
    // recent visit will be moved to the head
    list<pair<int,int>> l; // pair(key,val)
    unordered_map<int,list<pair<int,int>>::iterator> m; // key -> iterator in list
    
    LRUCache(int capacity) {
        cap = capacity;
    }
    
    int get(int key) {
        if (!m.count(key)) return -1;
        int res=(*m[key]).second;
        l.splice(l.begin(), l, m[key]); //move key to the first
        return res;
    }
    
    void put(int key, int value) {
        if (m.count(key)) l.erase(m[key]);
        
        l.push_front(make_pair(key,value));
        m[key] = l.begin();
        
        if (l.size()>cap){     
            m.erase(l.back().first);
            l.pop_back();
        }  
    }
};

/**
 * 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);
 */

 

本题也可以用一个 unordered_map,key -> <value, list iterator>,list 里按照顺序只存放 key。

 

C++ list splice

第一个 iterator 表示插入的起始位置,该 iterator 在 splice 后不会失效,依旧指向原来的元素。

第二个 iterator 如果原本也是指向当前 list,则不会失效,splice 后依旧指向原来的元素。如果不是,则会失效。

single element (2)
void splice (const_iterator position, list& x, const_iterator i);
void splice (const_iterator position, list&& x, const_iterator i);
int main() {
    list<int> l;
    l.push_back(1);
    l.push_back(2);
    l.push_back(3);
    
    auto it=l.begin(); advance(it,2); // point 3
    auto it2=l.begin(); // point 1
    l.splice(it2,l,it);
    for (auto x:l) cout<<x<<' '; // 3 1 2
    cout << *it; // point 3
    cout << *it2; // point 1
    return 0;
}

 

posted @ 2018-11-02 07:54  約束の空  阅读(110)  评论(0)    收藏  举报