代码改变世界

leetcode-LRU

2014-12-01 21:03  欧陈庚  阅读(309)  评论(0编辑  收藏  举报

题目:

实现 近期最少使用算法的缓存算法。即实现一个缓冲区(key-value数据对),要求满足下面两种操作:

  • get(key) - 返回key对应的value,如果没有当前这个key,则返回-1
  • set(key, value) 更新或者插入一个新的缓存k-V对,如果缓存区已经满了,则删除最少使用的。
  • 缓存区的大小在程序开始的时候初始化

题目链接:https://oj.leetcode.com/problems/lru-cache/

解法:

维护一个双向链表list,每个节点里面存储(key,value,preNode,nextNode)这样一个四元组。

维护一个索引(通过map实现),map的key是缓存数据的key,map的value是该key对应的node的指针,即地址。

当get(key)操作的时候,完成下面2个操作:从map中寻找key对应的地址,1:找不到返回-1;2:找到的话,将该节点移至表头,返回该节点的值。

当set(key,value)操作的时候,查找map的索引,找到就更新地址对应的值域,找不到就new一个新的节点;不管该节点是否已经存在,均需要将该节点移至表头。

如果在插入新的k-v缓存数据的时候,如果缓存区的大小满了,则删除list队尾的节点。

代码

class LRUCache{
public:
    struct node
    {
        int key;
        int value;
        node(int k,int v):key(k),value(v){}
    };
    LRUCache(int capacity1) {
        capacity = capacity1;
    }
    
    int get(int key) {
        unordered_map<int, node *>::iterator it = pos.find(key);
    if(it == pos.end())
        return -1;
    node * check = it->second;
    int result = check->value;
    linked.remove(check);
    linked.push_front(check);
    }
    
    void set(int key, int value) {
        unordered_map<int, node *>::iterator it = pos.find(key);

    if(it != pos.end())
    {
        node *t = it->second;
        t->value = value;
        linked.remove(t);
        linked.push_front(t);
    }
    else
    {
        node *t = new node(key, value);
        pos.insert(make_pair(key, t));
        if(linked.size() < capacity)
        {
            linked.push_front(t);
        }
        else
        {
            node *temp = linked.back();
            linked.pop_back();
            linked.push_front(t);
            pos.erase(temp->key);
            delete temp;
        }
    }
    }
    
    private:
    int capacity;
    unordered_map<int, node *> pos;
    list<node *> linked;
};