LRU算法思想,可粗略参考这篇文章:传送门

    首先定义节点:

struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};

    至于要实现这个题目的要求,就这样解决:利用list来实现一个特殊的“栈”,这个“栈”中的元素每当被访问就被提到栈顶(即该list第一个位置,利用list函数splice实现),每当“栈”满,适逢要加入新元素,则移除“栈”底元素。

    为了实现对该list实现的栈的随机访问,维护一个unordered_map(基于hash实现),键-值为<key, list::iterator>对,这样可以在时间复杂度O(1)内获得指定key的元素的iterator。当元素从栈底(即list::back())被移除时,同时移除map中对应项。当元素在被访问后被提前到“栈顶”,同样更新map中对应键值的元素的iterator.

    本题实现细节参考了这位仁兄:传送门,不敢掠美,共同学习。

class LRUCache{
private:
	list<Node> s;
	unordered_map<int, list<Node>::iterator> addr;
	int size;
public:
	LRUCache(int capacity) :size(capacity){	}

	int get(int key) {

		if (addr.find(key) == addr.end())
			return -1;
		s.splice(s.begin(), s, addr[key]);
		addr[key] = s.begin();
		return addr[key]->value;
	}

	void set(int key, int value) {
		Node* target = NULL;
		if ( addr.find(key)!= addr.end())
		{
			addr[key]->value = value;
			s.splice(s.begin(), s, addr[key]);
			addr[key] = s.begin();			
		}
		else{
			if (s.size() == size)
			{
				addr.erase(s.back().key);
				s.pop_back();
			}
			s.push_front(Node(key,value));
			addr[key] = s.begin();
			
		}
	}
};


posted on 2014-07-18 21:48  xlert  阅读(206)  评论(0编辑  收藏  举报