LRU缓存
思路
使用list维护访问元素的时间,最近访问的靠近头部,很久没有访问的靠近尾部。使用map维护key以及对应的value。
在获取元素的时候
判断map里面是否存在,map里面存在的话把对应的value返回,并且还要对list进行操作。即在list里面删除当前key,然后把当前key添加在list的头部。get方法也是对key进行了访问,所以要把当前key放到list的头部,代表最近访问。
在put元素的时候
- 判断map里面是否存在,如果存在的话,直接修改value,并且调整list里面的访问顺序(即在list里面删除key,再添加到list头部)
- 如果map里面不存在,判断map.size和capacity的大小
①如果map.size() == capacity,就要移除一个最久没有访问到的元素,即list的最后一个位置的元素,并且从map里面进行删除。然后把新的key和value添加到map和list里面;
②map.size() < capacity,直接把key和value添加到list和map里面。
class LRUCache {
/**
使用list维护时间
每次添加新元素或者访问已经存在的元素的时候,都把该元素从list里面删除,然后再添加到list的头部,
这样当容量不够且当前key不在list里面的时候,只需要移除list最后一个位置的元素,并且把map里面的对应
元素移除,再添加新元素就可以了。
*/
int capacity;
Map<Integer, Integer> map;
List<Integer> list;
public LRUCache(int capacity) {
this.capacity = capacity;
map = new HashMap<>();
list = new ArrayList<>();
}
public int get(int key) {
int result = -1;
if(map.containsKey(key)) {
list.remove(list.indexOf(key));
list.add(0, key);
result = map.get(key);
}
return result;
}
public void put(int key, int value) {
if(map.containsKey(key)) {
map.put(key, value);
list.remove(list.indexOf(key));
list.add(0, key);
}else{
if(map.size() == capacity) {
int r = list.get(list.size() - 1);
map.remove(r);
list.remove(list.size() - 1);
map.put(key, value);
list.add(0, key);
}else {
map.put(key, value);
list.add(0, key);
}
}
}
}
/**
* Your LRUCache object will be instantiated and called as such:
* LRUCache obj = new LRUCache(capacity);
* int param_1 = obj.get(key);
* obj.put(key,value);
*/