LeetCode 146. LRU缓存
题目描述
设计和实现一个 LRU (Least Recently Used) 缓存机制。它应该支持以下操作:
get(key)
:如果缓存中存在key
,则返回value
,否则返回-1
。put(key, value)
:如果缓存已满,移除最久未使用的项,然后插入新的key-value
对。如果key
已存在,则更新其value
。
Java 实现解法
解法:使用哈希表和双向链表
import java.util.HashMap;class LRUCache {private class Node {int key, value;Node prev, next;Node(int key, int value) {this.key = key;this.value = value;}}private HashMap<Integer, Node> cache;private Node head, tail;private int capacity;public LRUCache(int capacity) {this.capacity = capacity;cache = new HashMap<>();head = new Node(0, 0); // 虚拟头节点tail = new Node(0, 0); // 虚拟尾节点head.next = tail;tail.prev = head;}private void addNode(Node node) {node.prev = head;node.next = head.next;head.next.prev = node;head.next = node;}private void removeNode(Node node) {Node prev = node.prev;Node next = node.next;prev.next = next;next.prev = prev;}private Node popTail() {Node res = tail.prev;removeNode(res);return res;}public int get(int key) {if (!cache.containsKey(key)) return -1;Node node = cache.get(key);removeNode(node);addNode(node);return node.value;}public void put(int key, int value) {if (cache.containsKey(key)) {Node node = cache.get(key);removeNode(node);node.value = value;addNode(node);} else {Node newNode = new Node(key, value);if (cache.size() >= capacity) {Node tail = popTail();cache.remove(tail.key);}addNode(newNode);cache.put(key, newNode);}}
}
解题思路
- 使用一个哈希表存储键值对。
- 使用双向链表保持元素的使用顺序,头部表示最近使用,尾部表示最久未使用。
- 当访问元素时,将其移动到链表的头部;当缓存满时,移除链表尾部元素。
- 复杂度分析:时间复杂度:get:O(1) ,put:O(1)
空间复杂度:O(capacity),存储缓存和链表节点。