• leetcode LRU Cache


    题目连接

    https://leetcode.com/problems/lru-cache/  

    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]);
    	}
    };
  • 相关阅读:
    网页中防拷贝、屏蔽鼠标右键代码
    Enterprise Library Exception Handling Application Block Part 1
    vs debug 技巧
    Winforms:消除WebBrowser的GDI Objects泄露
    WinForm窗体之间交互的一些方法
    TableLayoutPanel用法
    Winforms:把长ToolTip显示为多行
    Winforms: 不能在Validating时弹出有模式的对话框
    Winforms: 复杂布局改变大小时绘制错误
    读取Excel默认工作表导出XML
  • 原文地址:https://www.cnblogs.com/GadyPu/p/5040297.html
Copyright © 2020-2023  润新知