146. LRU缓存机制
146. LRU缓存机制
力扣原题传送门
初次解题思路
哈希表+双向链表,由于被禁用LinkedHashMap类,自己代码实现。
public class LRUCache {
private HashMap<Integer, Node> hashMap;
private int size;
private AtomicInteger count = new AtomicInteger(0);
private Integer lastIndexKey;
private Integer firstIndexKey;
public LRUCache(int capacity) {
if (capacity < 1) {
throw new RuntimeException("capacity必须大于零");
}
this.hashMap = new HashMap<>(capacity);
this.size = capacity;
}
public int get(int key) {
int value = hashMap.get(key) != null ? hashMap.get(key).getValue() : -1;
if (value != -1) {
swap(key, value, hashMap.get(key));
}
return value;
}
public void put(int key, int value) {
Node node = hashMap.get(key);
if (node == null) {
putNewKey(key, value);
} else {
swap(key, value, node);
}
}
private void putNewKey(int key, int value) {
Node node = new Node();
// node.setHead(lastIndexKey);
node.setValue(value);
// 第一条数据入map
if (count.get() == 0) {
this.firstIndexKey = key;
this.lastIndexKey = key;
hashMap.put(key, node);
this.count.incrementAndGet();
return;
}
// 非第一条数据入map,当map已满时
if (count.get() == size) {
Node oldFirstNode = hashMap.get(firstIndexKey);
hashMap.remove(firstIndexKey);
if (oldFirstNode != null && oldFirstNode.getTail() != null) {
this.firstIndexKey = oldFirstNode.getTail();
hashMap.get(oldFirstNode.getTail()).setHead(null);
} else {
this.firstIndexKey = key;
this.lastIndexKey = key;
}
Node oldLastNode = hashMap.get(this.lastIndexKey);
if (oldLastNode != null) {
oldLastNode.setTail(key);
node.setHead(this.lastIndexKey);
} else {
this.firstIndexKey = key;
}
this.lastIndexKey = key;
hashMap.put(key, node);
} else {
this.count.incrementAndGet();
Node oldLastNode = hashMap.get(this.lastIndexKey);
oldLastNode.setTail(key);
node.setHead(this.lastIndexKey);
this.lastIndexKey = key;
hashMap.put(key, node);
}
}
private void swap(int key, int value, Node node) {
if (size == 1 || Objects.equals(this.lastIndexKey, key)) {
this.hashMap.get(this.lastIndexKey).setValue(value);
return;
}
node.setValue(value);
if (node.getHead() == null) {
Node oldFirst = node;
hashMap.remove(this.firstIndexKey);
this.firstIndexKey = oldFirst.getTail();
if (oldFirst.getTail() != null) {
this.hashMap.get(oldFirst.getTail()).setHead(null);
}
} else {
hashMap.remove(node);
if (node.getHead() != null) {
this.hashMap.get(node.getHead()).setTail(node.getTail());
}
if (node.getTail() != null) {
this.hashMap.get(node.getTail()).setHead(node.getHead());
}
}
hashMap.get(this.lastIndexKey).setTail(key);
node.setHead(this.lastIndexKey);
node.setTail(null);
this.lastIndexKey = key;
hashMap.put(key, node);
}
public class Node {
private int value;
private Integer head;
private Integer tail;
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public Integer getHead() {
return head;
}
public void setHead(Integer head) {
this.head = head;
}
public Integer getTail() {
return tail;
}
public void setTail(Integer tail) {
this.tail = tail;
}
@Override
public String toString() {
return "Node{" +
"value=" + value +
", head=" + head +
", tail=" + tail +
'}';
}
}
public HashMap<Integer, Node> getHashMap() {
return hashMap;
}
public void setHashMap(HashMap<Integer, Node> hashMap) {
this.hashMap = hashMap;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public AtomicInteger getCount() {
return count;
}
public void setCount(AtomicInteger count) {
this.count = count;
}
public Integer getLastIndexKey() {
return lastIndexKey;
}
public void setLastIndexKey(Integer lastIndexKey) {
this.lastIndexKey = lastIndexKey;
}
public Integer getFirstIndexKey() {
return firstIndexKey;
}
public void setFirstIndexKey(Integer firstIndexKey) {
this.firstIndexKey = firstIndexKey;
}
}
/**
* 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);
*/
力扣官方解法
LinkedHashMap简直为这题目量身定做。
class LRUCache extends LinkedHashMap<Integer, Integer>{
private int capacity;
public LRUCache(int capacity) {
super(capacity, 0.75F, true);
this.capacity = capacity;
}
public int get(int key) {
return super.getOrDefault(key, -1);
}
public void put(int key, int value) {
super.put(key, value);
}
@Override
protected boolean removeEldestEntry(Map.Entry<Integer, Integer> eldest) {
return size() > capacity;
}
}
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/lru-cache/solution/lruhuan-cun-ji-zhi-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。