23春招面试- Go实现lru算法

1、手撕lru算法,使用哈希表和双向链表实现

面试中提到的让手撕lru算法的实现,下面我们简单说一下步骤,具体代码也有相关注释,但是最主要的就是对lru算法的一个思路,顺着思路去写更好!!!!

  • 首先定义一个lru的缓存结构体四个字段,cap(容量)、size(当前缓存大小)、cache(缓存哈希表)、lruList(双向链表),再定义一个k,v结构体Pair
  • 新建一个lru缓存对象,对lru结构体初始化字段
  • Get(key)方法,获取value,如果key存在,将这个元素放到链表第一位
  • Put(key,value)方法,将key,value放入hash表和list,核心方法!!!
    • 先判断存不存在这个key,如果存在,提到list第一位
    • 如果不存在,判断当前缓存大小满了没有,cap==size
    • 如果满了就要淘汰链表最后一位数据,并且从哈希表删除
    • 如果没满,将最新的kv放到list第一位,并且加入hash表

核心数据结构图示:

23春招面试- Go实现lru算法_第1张图片

type LRUCache struct {
	cap     int                   // 容量
	size    int                   // 当前缓存大小
	cache   map[int]*list.Element // 哈希表存储键值对
	lruList *list.List            // 双向链表键值对
}

type Pair struct {
	key   int
	value int
}

// NewLRUCache 创建一个 LRUCache 对象
func NewLRUCache(capacity int) *LRUCache {
	return &LRUCache{
		cap:     capacity,
		cache:   make(map[int]*list.Element),
		lruList: list.New(),
	}
}

// Get 获取一个键值对的 value,如果存在则将其移到双向链表头部
func (c *LRUCache) Get(key int) int {
	if elem, ok := c.cache[key]; ok {
		c.lruList.MoveToFront(elem) // 如果查询的元素存在,将把它放到链表的第一位
		return elem.Value.(*Pair).value
	}
	return -1
}

// Put 将k,v放入哈希表和双向链表
func (c *LRUCache) Put(key, value int) {
	if elem, ok := c.cache[key]; ok {
		elem.Value.(*Pair).value = value
		c.lruList.MoveToFront(elem) // 如果放入的元素重复,或是换value,就是使用了这个key,将这个元素放到第一个位置
	} else { // 如果哈希表没有这个key
		if c.size == c.cap { // 首先判断缓存满了没有
			delete(c.cache, c.lruList.Back().Value.(*Pair).key) // 从哈希表删除最后一个元素
			c.lruList.Remove(c.lruList.Back())                  // 再从双向链表删除最后一个元素
			c.size--                                            // 缓存大小减1
		}
		c.cache[key] = c.lruList.PushFront(&Pair{key, value}) // 将新的k, v放入双向链表第一个位,并且将其放入哈希表
		c.size++
	}
}

func main() {
	lruCache := NewLRUCache(2)
	lruCache.Put(1, 1)
	lruCache.Put(2, 2)
	fmt.Println(lruCache.Get(1)) // 1
	lruCache.Put(3, 3)
	fmt.Println(lruCache.Get(2)) // -1
	lruCache.Put(4, 4)
	fmt.Println(lruCache.Get(1)) // -1
	fmt.Println(lruCache.Get(3)) // 3
	fmt.Println(lruCache.Get(4)) // 4
}

你可能感兴趣的:(面试,golang,算法)