
解题思路:
- 继承 LinkedHashMap: 内置双向链表,自动维护节点的插入顺序和访问顺序。
- LRU 淘汰逻辑: 覆盖 removeEldestEntry,当元素数量超过 capacity 时,移除最旧条目。removeEldestEntry 方法提供钩子(Hook)机制,在扩容时自动检查是否需要淘汰最旧节点自动触发,通过 LinkedHashMap 的内部机制,无需手动管理链表。
Java代码:
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);}@Overrideprotected boolean removeEldestEntry(Map.Entry<Integer, Integer> eldest) {return size() > capacity; }
}
哈希表+双向链表实现:
public class LRUCache {class DLinkedNode {int key;int value;DLinkedNode prev;DLinkedNode next;public DLinkedNode() {}public DLinkedNode(int _key, int _value) {key = _key; value = _value;}}private Map<Integer, DLinkedNode> cache = new HashMap<Integer, DLinkedNode>();private int size;private int capacity;private DLinkedNode head, tail;public LRUCache(int capacity) {this.size = 0;this.capacity = capacity;head = new DLinkedNode();tail = new DLinkedNode();head.next = tail;tail.prev = head;}public int get(int key) {DLinkedNode node = cache.get(key);if (node == null) {return -1;}moveToHead(node);return node.value;}public void put(int key, int value) {DLinkedNode node = cache.get(key);if (node == null) {DLinkedNode newNode = new DLinkedNode(key, value);cache.put(key, newNode);addToHead(newNode);++size;if (size > capacity) {DLinkedNode tail = removeTail();cache.remove(tail.key);--size;}}else {node.value = value;moveToHead(node);}}private void addToHead(DLinkedNode node) {node.prev = head;node.next = head.next;head.next.prev = node;head.next = node;}private void removeNode(DLinkedNode node) {node.prev.next = node.next;node.next.prev = node.prev;}private void moveToHead(DLinkedNode node) {removeNode(node);addToHead(node);}private DLinkedNode removeTail() {DLinkedNode res = tail.prev;removeNode(res);return res;}
}
复杂度分析:

解题思路(迭代):
- 终止条件: 当前节点为空时返回。
- 递归逻辑: 先遍历左子树,再访问当前节点,最后遍历右子树。
Java代码:
class Solution {public List<Integer> inorderTraversal(TreeNode root) {List<Integer> result = new ArrayList<>();inorderHelper(root, result);return result;}private void inorderHelper(TreeNode node, List<Integer> list) {if (node == null) return;inorderHelper(node.left, list);list.add(node.val);inorderHelper(node.right, list);}
}
复杂度分析:
- 时间复杂度: 所有节点访问一次,时间复杂度均为 O(n)。
- 空间复杂度: 栈深度由树的高度决定,平衡树为 O(logn),链表为 O(n)。
解题思路(递归):
- 显式栈: 模拟递归调用栈,通过循环将左子树节点压栈,弹出后处理右子树。
Java代码:
class Solution {public List<Integer> inorderTraversal(TreeNode root) {List<Integer> result = new ArrayList<>();Stack<TreeNode> stack = new Stack<>();TreeNode curr = root;while (curr != null || !stack.isEmpty()) {while (curr != null) {stack.push(curr);curr = curr.left;}curr = stack.pop();result.add(curr.val);curr = curr.right;}return result;}
}
复杂度分析:
- 时间复杂度: 所有节点访问一次,时间复杂度均为 O(n)。
- 空间复杂度: 栈最多存储 n 个节点(退化链表时),故空间复杂度为 O(n)。