📑 题目:146. LRU 缓存机制

🚀 本题 LeetCode 传送门

题目大意

运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制 。 实现 LRUCache 类:

  • LRUCache(int capacity) 以正整数作为容量 capacity 初始化 LRU 缓存
  • int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 。
  • void put(int key, int value) 如果关键字已经存在,则变更其数据值;如果关键字不存在,则插入该组「关键字-值」。当缓存容量达到上限时,它应该在写入新数据之前删除最久未使用的数据值,从而为新的数据值留出空间。

进阶:你是否可以在 O(1) 时间复杂度内完成这两种操作?

解题思路

  • 这一题是 LRU 经典面试题,详细解释见第三章模板。

代码

  1. package leetcode
  2. type LRUCache struct {
  3. head, tail *Node
  4. Keys map[int]*Node
  5. Cap int
  6. }
  7. type Node struct {
  8. Key, Val int
  9. Prev, Next *Node
  10. }
  11. func Constructor(capacity int) LRUCache {
  12. return LRUCache{Keys: make(map[int]*Node), Cap: capacity}
  13. }
  14. func (this *LRUCache) Get(key int) int {
  15. if node, ok := this.Keys[key]; ok {
  16. this.Remove(node)
  17. this.Add(node)
  18. return node.Val
  19. }
  20. return -1
  21. }
  22. func (this *LRUCache) Put(key int, value int) {
  23. if node, ok := this.Keys[key]; ok {
  24. node.Val = value
  25. this.Remove(node)
  26. this.Add(node)
  27. return
  28. } else {
  29. node = &Node{Key: key, Val: value}
  30. this.Keys[key] = node
  31. this.Add(node)
  32. }
  33. if len(this.Keys) > this.Cap {
  34. delete(this.Keys, this.tail.Key)
  35. this.Remove(this.tail)
  36. }
  37. }
  38. func (this *LRUCache) Add(node *Node) {
  39. node.Prev = nil
  40. node.Next = this.head
  41. if this.head != nil {
  42. this.head.Prev = node
  43. }
  44. this.head = node
  45. if this.tail == nil {
  46. this.tail = node
  47. this.tail.Next = nil
  48. }
  49. }
  50. func (this *LRUCache) Remove(node *Node) {
  51. if node == this.head {
  52. this.head = node.Next
  53. node.Next = nil
  54. return
  55. }
  56. if node == this.tail {
  57. this.tail = node.Prev
  58. node.Prev.Next = nil
  59. node.Prev = nil
  60. return
  61. }
  62. node.Prev.Next = node.Next
  63. node.Next.Prev = node.Prev
  64. }