leetcode LRU Cache

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

Description

Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and set.

get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.
set(key, value) - Set or insert the value if the key is not already present. When the cache reached its capacity, it should invalidate the least recently used item before inserting a new item.
题目大意:为LRU Cache设计一个数据结构,它支持两个操作
 (1)get(key):如果key在cache中,则返回对应的value值,否则返回-1
 (2)set(key,value):如果key不在cache中,则将该(key,value)插入cache中(注意,如果
cache已满,则必须把最近最久未使用的元素从cache中删除);如果key在cache中,则重置value的值。

思路:用一个变量表示时间戳,每当插入key时,时间戳++,当插入元素已存在数据中更新它的value时也要更新他的时间戳。若cache已满先要删除时间戳最早的元素,再插入新元素。
当get元素时,它的时间戳必须更新(毕竟这个元素正在访问中。。)

思路理清了,代码实现就很简单了。。

用map让时间戳与key对应,用平衡树存储key,value, 时间戳。。

具体如下:

class LRUCache {
private:
    const int INF = ~0u >> 1;
public:
    LRUCache() = default;
    LRUCache(int capacity) {
        idx = 0, size = capacity;
        null = new Node(INF, INF, -1, 0, NULL);
        root = null;
    }
    ~LRUCache() { clear(root); root = NULL; }
    int get(int key) {
        Node *x = find(key);
        if (x->s) {
            MP.erase(MP.find(x->idx));
            MP[idx] = x->key;
            x->idx = idx++;
        }
        return !x->s ? -1 : x->val;
    }
    void set(int key, int value) {
        Node *x = find(key);
        if (!x->s && root->s != this->size) {
            insert(root, key, value, idx);
            MP[idx++] = key;
        } else {
            if (key == x->key) {
                x->val = value;
                MP.erase(MP.find(x->idx));
                MP[idx] = x->key;
                x->idx = idx++;
            } else {
                auto ret = MP.begin();
                erase(root, ret->second);
                MP.erase(ret);
                insert(root, key, value, idx);
                MP[idx++] = key;
            }
        }
    }
private:
    int idx, size;
private:
    map<int, int> MP;
    struct Node {
        int key, val, idx, s;
        Node *ch[2];
        Node(int i, int j, int k, int l, Node *p) {
            key = i, val = j, idx = k, s = l;
            ch[0] = ch[1] = p;
        }
        inline bool cmp(int v) const {
            return v > key;
        }
        inline void push_up() {
            s = ch[0]->s + ch[1]->s + 1;
        }
    }*root, *null;
    inline void rotate(Node *&x, bool d) {
        Node *k = x->ch[!d]; x->ch[!d] = k->ch[d]; k->ch[d] = x;
        k->s = x->s, x->push_up(), x = k;
    }
    inline void Maintain(Node *&x, bool d) {
        if (!x->ch[d]->s) return;
        if (x->ch[d]->ch[d]->s > x->ch[!d]->s) rotate(x, !d);
        else if (x->ch[d]->ch[!d]->s > x->ch[!d]->s) rotate(x->ch[d], d), rotate(x, !d);
        else return;
        Maintain(x, 0), Maintain(x, 1);
    }
    inline void insert(Node *&x, int key, int val, int idx) {
        if (!x->s) { x = new Node(key, val, idx, 1, null); return; }
        x->s++;
        bool d = x->cmp(key);
        insert(x->ch[d], key, val, idx);
        x->push_up();
        Maintain(x, d);
    }
    inline void erase(Node *&x, int key) {
        if (!x->s) return;
        x->s--;
        bool d = x->cmp(key);
        if (x->key == key) {
            Node *ret = NULL;
            if (!x->ch[0]->s || !x->ch[1]->s) {
                ret = x;
                x = ret->ch[0]->s ? ret->ch[0] : x->ch[1];
                delete ret;
            } else {
                ret = x->ch[1];
                for (; ret->ch[0]->s; ret = ret->ch[0]);
                x->key = ret->key, x->val = ret->val, x->idx = ret->idx;
                erase(x->ch[1], x->key);
            }
        } else {
            erase(x->ch[d], key);
        }
        if (x->s) x->push_up();
    }
    inline Node* find(int key) {
        Node *x = root;
        while (x->s && x->key != key) x = x->ch[key > x->key];
        return x;
    }
    inline void clear(Node *x) {
        if (!x->s) return;
        clear(x->ch[0]);
        delete x;
        clear(x->ch[1]);
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值