[Leetcode] LRU cache

Problem:

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.

Thought:

Use a HashMap along with a doubly linked list to achieve the O(1) running time for both get and set.

package leetcode_Java;

import java.util.Comparator;
import java.util.HashMap;
import java.util.PriorityQueue;


public class LRUCache {

	HashMap <Integer, ListEntry> map = new HashMap<Integer, ListEntry>();
	DoublyLinkedList list;
	
	public LRUCache(int capacity) {
		list = new DoublyLinkedList(capacity, map);
	}

	public int get(int key) {
		ListEntry entry = map.get(key);
		if(entry == null){
			return -1;
		}else{
			list.MoveToHead(entry);
			return entry.value;
		}
	}

	public void set(int key, int value) {
		ListEntry entry = map.get(key);
		if(entry == null){
			ListEntry newEntry = new ListEntry(null, null, value, key);
			map.put(key, newEntry);
			list.Add(newEntry);
		}else{
			entry.value = value;
			list.MoveToHead(entry);
		}
	}
	
	
}

class DoublyLinkedList{
	ListEntry head;
	ListEntry tail;
	int capacity;
	int currentSize;
	
	HashMap <Integer, ListEntry> map;
	
	public DoublyLinkedList(int capacity, HashMap <Integer, ListEntry> map){
		this.capacity = capacity;
		this.currentSize = 0;
		this.map = map;
	}
	
	public void Add(ListEntry entry){
		if(currentSize < capacity){
			if(head == null){
				head = entry;
				tail = entry;
			}else{
				head.prev = entry;
				entry.next = head;
				head = entry;
			}
			currentSize++;
			
		}else{
			head.prev = entry;
			entry.next = head;
			head = entry;
			
			//remove tail
			map.remove(tail.key);
			tail = tail.prev;
			tail.next = null;
		}
	}
	
	//Assume that entry has already existed somewhere in the doubly linked list
	public void MoveToHead(ListEntry entry){
		
		if(entry == head){
			return;
			
		}else if(entry == tail){
			tail = entry.prev;
			entry.prev.next = null;
			
		}else{ // in the middle
			entry.prev.next = entry.next;
			entry.next.prev = entry.prev;
		}
		
		head.prev = entry;
		entry.next = head;
		entry.prev = null;
		head = entry;
	}
}


// Node type of a doubly linked list
class ListEntry{
	ListEntry prev;
	ListEntry next;
	int value;
	int key;
	
	public ListEntry(ListEntry prev, ListEntry next, int value, int key) {
		super();
		this.prev = prev;
		this.next = next;
		this.value = value;
		this.key = key;
	}
	
}

  

posted @ 2014-04-10 02:58  门对夕阳  阅读(354)  评论(0编辑  收藏  举报