编程算法面试题

LRU缓存:HashMap+双向链表

实现一个O(1)的LRU缓存。

为什么面试官会问这道题

系统结构类代码题最高频,LeetCode 146,几乎所有大厂都问。

如何回答

  1. 1

    要求:get和put都O(1);容量满时淘汰最久未用。

  2. 2

    HashMap单独:查O(1)但无序。链表单独:有序但查O(n)。组合:map→链表节点,双向链表支持O(1)摘除。

  3. 3

    get(key):map查节点→摘除→移到头。put(key):存在就更新+移头;不存在就建节点插头,超容量删尾。

  4. 4

    必须双向链表——中间节点O(1)摘除要知道前驱。

  5. 5

    用哨兵头尾伪节点避免边界null判断。

参考回答示例

HashMap指向双向链表节点。get:map查到节点、摘下、插到头、返回值。put:存在就改值并移头;不存在造节点插头,超容量就删尾并同步map。每步O(1):map O(1)、知道节点后双向链表摘O(1)、头尾插O(1)。Java的LinkedHashMap就是这个结构——重写removeEldestEntry五行搞定——但面试要你展示内部实现。两个坑:删尾时一定也删map里的键、用哨兵头尾避免null判断。

实用技巧

  • LinkedHashMap(accessOrder=true)是真实代码里的五行版。

  • LFU(按频率)是常见追问——要桶结构,比LRU难。

  • 即答侠背了40行Java版和LFU扩展。

常见问题

为什么不能用单链表?

中间节点O(1)摘除要知道前驱。单链表要从头走O(n)。

并发访问怎么办?

朴素实现不是线程安全的。并发LRU用Caffeine或加锁——完全无锁的LRU很难。

面试时担心忘词?即答侠实时助你

即答侠 AI 实时监听面试对话,自动识别问题并即时生成回答建议——无感辅助,让你从容应对每一道题。

免费试用即答侠