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]);
	}
};

 

posted @ 2015-12-11 21:30  GadyPu  阅读(252)  评论(0编辑  收藏  举报