leetCode:LRU Cache TreeMap应用

原题如下:

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,对LRU的解释为:Replace the page that has not been used for the longest period of time,即最长时间未被访问的页面,访问包括set和get。

很容易想到用TreeMap来实现,但是实现过程还是有点曲折,TreeMap是有序的Map,是根据key排序的,TreeMap和HashMap根据hashCode()方法和equals()方法来比较key值是否相等,但TreeMap是根据key元素的compareTo方法来排序,在这里因为我们关心的是时间,所以我们希望元素安装时间排序,同时TreeMap结构的key中包含题目中的key值,所以需要一种新的数据结构KeyTime,KeyTime包括key和访问时间,让TreeMap安装访问时间排序,所以需要重写compareTo方法

完整代码如下:

keyTime用于保存key和访问时间。caches用来保存KeyTime和对应的值。注意每次访问都要修改时间。


import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

//Replace the page that has not been used for the longest period of time
public class LRUCache {
	
	private int size;
	long timeCounter = 0;  //模拟时间点
	private HashMap<Integer,Long> keyTime = new HashMap<Integer,Long>(); //不需要有序,这个地方改成TreeMap会变慢(要维持顺序)
	private TreeMap<KeyTime,Integer> caches = new TreeMap<KeyTime,Integer>(); //有序
	
    public LRUCache(int capacity) {
        this.size = capacity;
    }
    
    public int get(int key) {
    	if(keyTime.containsKey(key)){
    		long newTime = timeCounter++;
    		KeyTime kt = new KeyTime(key,keyTime.get(key).longValue());
    		int value = caches.get(kt);
    		keyTime.put(key, newTime);
    		caches.remove(kt);
    		caches.put(new KeyTime(key,newTime), value);
    		return value;
    	}
    	return -1;
    }
    
    public void set(int key, int value) {
		long newTime = timeCounter++;
    	if(keyTime.containsKey(key)){	                  //已经存在
    		long oldTime = keyTime.get(key);
    		keyTime.put(key, newTime);
    		caches.remove(new KeyTime(key,oldTime));
    		caches.put(new KeyTime(key,newTime), value);
    	}else if(keyTime.size()<this.size){               //不存在但未满
    		keyTime.put(key, newTime);
    		caches.put(new KeyTime(key,newTime), value);
    	}else{                                            //不存在,而且满了
    		 Map.Entry<KeyTime,Integer> firstEntry = caches.firstEntry();
    		 int k = firstEntry.getKey().key;
    		 long time = firstEntry.getKey().time;
    		 caches.remove(new KeyTime(k,time));
    		 keyTime.remove(k);
    		 keyTime.put(key, newTime);
    		 caches.put(new KeyTime(key,newTime), value);
    	}
    }
    
	class KeyTime implements Comparable<KeyTime>{
		int key;
		long time;
		
		public KeyTime(int key,long time){
			this.key = key;
			this.time = time;
		}
		
		@Override
		public int compareTo(KeyTime o) {          //重写compareTo方法
			if(this.time<o.time){
				return -1;
			}else if(this.time>o.time){
				return 1;
			}
			return 0;
		}
	}
}


你可能感兴趣的:(leetCode:LRU Cache TreeMap应用)