0146. L R U Cache

# 146. LRU Cache#

## 题目 #

Design a data structure that follows the constraints of a  Least Recently Used (LRU) cache.

Implement the `LRUCache` class:

• `LRUCache(int capacity)` Initialize the LRU cache with positive size `capacity`.
• `int get(int key)` Return the value of the `key` if the key exists, otherwise return `1`.
• `void put(int key, int value)` Update the value of the `key` if the `key` exists. Otherwise, add the `key-value` pair to the cache. If the number of keys exceeds the `capacity` from this operation, evict the least recently used key.

Follow up:Could you do `get` and `put` in `O(1)` time complexity?

Example 1:

``````Input
["LRUCache", "put", "put", "get", "put", "get", "put", "get", "get", "get"]
[[2], [1, 1], [2, 2], [1], [3, 3], [2], [4, 4], [1], [3], [4]]
Output
[null, null, null, 1, null, -1, null, -1, 3, 4]

Explanation
LRUCache lRUCache = new LRUCache(2);
lRUCache.put(1, 1); // cache is {1=1}
lRUCache.put(2, 2); // cache is {1=1, 2=2}
lRUCache.get(1);    // return 1
lRUCache.put(3, 3); // LRU key was 2, evicts key 2, cache is {1=1, 3=3}
lRUCache.put(4, 4); // LRU key was 1, evicts key 1, cache is {4=4, 3=3}
lRUCache.get(3);    // return 3
lRUCache.get(4);    // return 4

``````

Constraints:

• `1 <= capacity <= 3000`
• `0 <= key <= 3000`
• `0 <= value <= 104`
• At most `3 * 104` calls will be made to `get` and `put`.

## 题目大意 #

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

## 解题思路 #

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

## 代码 #

``````package leetcode

type LRUCache struct {
Keys       map[int]*Node
Cap        int
}

type Node struct {
Key, Val   int
Prev, Next *Node
}

func Constructor(capacity int) LRUCache {
return LRUCache{Keys: make(map[int]*Node), Cap: capacity}
}

func (this *LRUCache) Get(key int) int {
if node, ok := this.Keys[key]; ok {
this.Remove(node)
return node.Val
}
return -1
}

func (this *LRUCache) Put(key int, value int) {
if node, ok := this.Keys[key]; ok {
node.Val = value
this.Remove(node)
return
} else {
node = &Node{Key: key, Val: value}
this.Keys[key] = node
}
if len(this.Keys) > this.Cap {
delete(this.Keys, this.tail.Key)
this.Remove(this.tail)
}
}

func (this *LRUCache) Add(node *Node) {
node.Prev = nil
}
if this.tail == nil {
this.tail = node
this.tail.Next = nil
}
}

func (this *LRUCache) Remove(node *Node) {
node.Next = nil
return
}
if node == this.tail {
this.tail = node.Prev
node.Prev.Next = nil
node.Prev = nil
return
}
node.Prev.Next = node.Next
node.Next.Prev = node.Prev
}
``````

Apr 8, 2023