福哥答案2020-09-18:

方法:哈希表 + 双向链表。
时间复杂度:对于 put 和 get 都是 O(1)。
空间复杂度:O(capacity),因为哈希表和双向链表最多存储 capacity+1 个元素。

代码用go语言编写,代码如下:

package test40_lru

import (
    "fmt"
    "testing"
)

/*
哈希表 + 双向链表
时间复杂度:对于 put 和 get 都是 O(1)O(1)。
空间复杂度:O(capacity),因为哈希表和双向链表最多存储 capacity+1 个元素。
*/
//https://leetcode-cn.com/problems/lru-cache/solution/lruhuan-cun-ji-zhi-by-leetcode-solution/
//go test -v -test.run TestLru
func TestLru(t *testing.T) {
    cache := NewLRUCache(2)

    cache.Put(1, 1)
    cache.Put(2, 2)
    cache.Get(1)    // 返回  1
    cache.Put(3, 3) // 该操作会使得关键字 2 作废
    cache.Get(2)    // 返回 -1 (未找到)
    cache.Put(4, 4) // 该操作会使得关键字 1 作废
    cache.Get(1)    // 返回 -1 (未找到)
    cache.Get(3)    // 返回  3
    cache.Get(4)    // 返回  4

}

type LRUCache struct {
    size       int
    capacity   int
    cache      map[int]*DLinkedNode
    head, tail *DLinkedNode
}

type DLinkedNode struct {
    key, value int
    prev, next *DLinkedNode
}

func NewDLinkedNode(key, value int) *DLinkedNode {
    return &DLinkedNode{
        key:   key,
        value: value,
    }
}

func NewLRUCache(capacity int) LRUCache {
    l := LRUCache{
        cache:    map[int]*DLinkedNode{},
        head:     NewDLinkedNode(0, 0),
        tail:     NewDLinkedNode(0, 0),
        capacity: capacity,
    }
    l.head.next = l.tail
    l.tail.prev = l.head
    return l
}

//获取元素
func (f *LRUCache) Get(key int) int {
    //如果缓存里未找到元素
    if _, ok := f.cache[key]; !ok {
        fmt.Println(-1)
        return -1
    }

    //缓存里有元素
    node := f.cache[key]

    //如果 key 存在,先通过哈希表定位,再移到头部
    f.moveToHead(node)
    fmt.Println(node.value)
    return node.value
}

//放入元素
func (f *LRUCache) Put(key int, value int) {
    //如果缓存里没有元素
    if _, ok := f.cache[key]; !ok {
        node := NewDLinkedNode(key, value)
        f.cache[key] = node
        //放在头部
        f.addToHead(node)
        f.size++
        //如果元素个数大于容量,需要删除元素
        if f.size > f.capacity {
            //删除链表尾部
            removed := f.removeTail()
            //删除map中的key
            delete(f.cache, removed.key)
            f.size--
        }
    } else { //缓存里有元素
        //获取元素
        node := f.cache[key]
        //修改值
        node.value = value
        //移动到链表头
        f.moveToHead(node)
    }
}

//添加到头节点
func (f *LRUCache) addToHead(node *DLinkedNode) {
    node.prev = f.head
    node.next = f.head.next
    f.head.next.prev = node
    f.head.next = node
}

//删除节点
func (f *LRUCache) removeNode(node *DLinkedNode) {
    node.prev.next = node.next
    node.next.prev = node.prev
}

//移动到头节点
func (f *LRUCache) moveToHead(node *DLinkedNode) {
    f.removeNode(node)
    f.addToHead(node)
}

//删除尾部
func (f *LRUCache) removeTail() *DLinkedNode {
    node := f.tail.prev
    f.removeNode(node)
    return node
}

执行结果如下:
在这里插入图片描述