【Leetcode】LRU Cache

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.

------------------------------------------------------------------------------------------------------------------------

No wonder the low pass rate. This question could be the top few hard among all leetcode problems. Classic and deeply testing interviewee's data structure ability.

When I came to this question problem firstly, I realize we need to build like a "HashQueue".

1<-2<-3<-4<-5, when "2" come again, it turns into 1<-3<-4<-5-<2.

Or 1<-2<-3<-4<-5, when 6 come for the first time, it turns into 2<-3<-4<-5-<6. We kicked out the oldest element. 

Thus, if we can build a hashtable / hashmap, ensuring the uniqueness of an element, and in the meantime first in first out OR update appeared element.

However, we don't have such a data structure called "hashqueue" so we have to build one on our own.

So my idea is like this: HashMap<key, Node>, where Node is {key, value, pre, next}. Node is basically containing all information and pointing to the pre or next element. Based on such data structure, we can easily manipulate the whole "stream", or say queue.

import java.util.HashMap;

public class LRU {
	//define how many element could contains in the cache
	int capacity;
	//we need a hashmap to ensure every incoming element is unique. 
	//By using hashmap, we can find corresponding Node to move.
	HashMap<Integer, Node> map = new HashMap<Integer, Node>();
	//we need to define the head (latest node) and end (least recent node) 
	Node head = null;
	Node end = null;
	
	public LRU(int capacity) {
		this.capacity = capacity;
	}
    
    public int get(int key) {
    	if(map.containsKey(key)){
    		Node n = map.get(key);
    		
    		remove(n);
    		//let n be the latest element
    		setHead(n);
    	}
		return -1;
    }
    
    private void remove(Node n){
    	if(n.pre!=null){
    		n.pre.next = n.next;
    	}
    	if(n.next!=null){
    		n.next.pre = n.pre;
    	}
    	
    		
    }
    
    private void setHead(Node n){
    	n.next = head;
    	n.pre = null;
    	head.pre = n;
    	head = n;
    	//not sure about below
    	 if(end ==null)
             end = head;
    }
    
    
    public void set(int key, int value) {
        if(map.get(key)!=null){
        	Node old = map.get(key);
        	remove(old);
        	setHead(old);
        }
        else{
        	Node new_ = new Node(key, value);
        	if(map.size() > capacity){
        		map.remove(end.key);
        		remove(end);
        		setHead(new_);
        	}
        	else{
        		setHead(new_);
        	}
        	map.put(key, new_);
        }
        
        	
    }
    
    //define the data structure of a single Node as a double-linkedlist
    class Node{
    	int key;
    	int value;
    	Node pre;
    	Node next;
    	public Node(int k, int v){
    		this.key = k;
    		this.value = v;
    	}
    }
}

 Moreover!!!!!

I found another method that directly extended LinkedHashMap, which largely facilitate the whole process.

import java.util.LinkedHashMap;
import java.util.Map.Entry;
 
public class LRUCache extends LinkedHashMap<Integer, Integer> {
   
    private int capacity;
   
    public LRUCache(int capacity) {
        super(capacity+1, 1.0f, true);  // for access order
        this.capacity = capacity;
    }
   
    public int get(int key) {
        if(super.get(key) == null)
            return -1;
        else
            return ((int) super.get(key));
    }
   
    public void set(int key, int value) {
        super.put(key, value);
    }
   
    protected boolean removeEldestEntry(Entry entry) {
        return (size() > this.capacity);
    }
}

What you need to know:

LinkedHashMap(int capacity, float fillRatio, boolean Order)

This constructor allows you to specify whether the elements will be stored in the linked list by insertion order, or by order of last access. If Order is true, then access order is used. If Order is false, then insertion order is used. .

protected boolean removeEldestEntry(Map.Entry eldest)

Returns true if this map should remove its eldest entry.


If you wanna know more about LinkedHashMap, here we go:

http://zhangshixi.iteye.com/blog/673789


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值