【LeetCode OJ】LRU Cache

Posted on 2014-04-03 22:56  卢泽尔  阅读(263)  评论(0)    收藏  举报

Problem Link:

http://oj.leetcode.com/problems/lru-cache/

Long long ago, I had a post for implementing the LRU Cache in C++ in my homepage:

http://www.cs.uml.edu/~jlu1/doc/codes/lruCache.html

 

So this time, I am trying to use Python to implement a LRU Cache.

However, the result is Time Limit Exceeded.....

My previous post is of C++ template version, but for this problem, the key and value are both integer, so I had a simpler version in C++ here.

I will keep trying to pass the test using python... damn efficiency...

#include <iostream>
#include <vector>
#include <map>

using namespace std;


struct LRUCacheEntry
{
	int key;
	int data;
	LRUCacheEntry* prev;
	LRUCacheEntry* next;
};

class LRUCache{
private:
	map<int, LRUCacheEntry*>        _mapping;
	vector<LRUCacheEntry*>      	_freeEntries;
	LRUCacheEntry *			head;
	LRUCacheEntry *			tail;
	LRUCacheEntry *			entries;
	
public:
    LRUCache(int capacity) {
        entries = new LRUCacheEntry[capacity];
        for (int i=0; i<capacity; i++)
			_freeEntries.push_back(entries+i);
		head = new LRUCacheEntry;
		tail = new LRUCacheEntry;
		head->prev = NULL;
		head->next = tail;
		tail->next = NULL;
		tail->prev = head;
    }
    
    ~LRUCache()
	{
		delete head;
		delete tail;
		delete [] entries;
	}
	
    int get(int key) {
        LRUCacheEntry* node = _mapping[key];
		if(node)
		{
			detach(node);
			attach(node);
			return node->data;
		}
		else return -1;
    }
    
    void set(int key, int value) {
        LRUCacheEntry* node = _mapping[key];
		if(node)
		{
			// Move the node to the head and update the value
			detach(node);
			node->data = value;
			attach(node);
		}
		else{
			if ( _freeEntries.empty() )
			{
			    // Get the last node
				node = tail->prev;
				// Move it to the head and update (key, value)
				// Update the map
				detach(node);
				_mapping.erase(node->key);
				node->data = value;
				node->key = key;
				_mapping[key] = node;
				attach(node);
			}
			else{
				node = _freeEntries.back();
				_freeEntries.pop_back();
				node->key = key;
				node->data = value;
				_mapping[key] = node;
				attach(node);
			}
		}
    }
    
private:
	void detach(LRUCacheEntry* node)
	{
		node->prev->next = node->next;
		node->next->prev = node->prev;
	}
	void attach(LRUCacheEntry* node)
	{
		node->next = head->next;
		node->prev = head;
		head->next = node;
		node->next->prev = node;
	}
};