LRUCache设计和实现

题目说明

数据结构设计

  1. 操作
  2. 关键点

实现1

package main

import (
	"fmt"
)

type Node struct {
	Key   interface{}
	Value interface{}
	pre   *Node
	next  *Node
}
type LRUCache struct {
	limit   int
	HashMap map[interface{}]*Node // k: 缓存key  v: 缓存v
	head    *Node
	end     *Node // 缓存中最后一个节点
}

func (l *LRUCache) removeNode(node *Node) interface{} {
	if node == l.end { // 删除尾节点
		l.end = l.end.pre
		l.end.next = nil
	} else if node == l.head { // 删除头节点
		l.head = l.head.next
		l.head.pre = nil
	} else { // 删除中间节点
		node.pre.next = node.next
		node.next.pre = node.pre
	}
	return node.Key
}

func (l *LRUCache) addNode(node *Node) {
	// 往空链表插入节点
	if l.end != nil {
		l.end.next = node
		node.pre = l.end
		node.next = nil
	}
	l.end = node
	if l.head == nil {
		l.head = node
	}
}

func (l *LRUCache) refreshNode(node *Node) {
	if node == l.end {
		return
	}
	l.removeNode(node) // 从链表中的任意位置移除原来的位置
	l.addNode(node)    // 添加到链表的尾部
}

func Constructor(capacity int) LRUCache {
	lruCache := LRUCache{limit: capacity}
	lruCache.HashMap = make(map[interface{}]*Node, capacity)
	return lruCache
}

func (l *LRUCache) Get(key interface{}) interface{} {
	if v, ok := l.HashMap[key]; ok {
		l.refreshNode(v)
		return v.Value
	} else {
		return -1
	}
}
func (l *LRUCache) Put(key, value interface{}) {
	if v, ok := l.HashMap[key]; !ok {
		if len(l.HashMap) >= l.limit {
			oldkey := l.removeNode(l.head)
			delete(l.HashMap, oldkey)
		}
		node := Node{Key: key, Value: value}
		l.addNode(&node)
		l.HashMap[key] = &node
	} else {
		v.Value = value
		l.refreshNode(v)
	}
}
func (l *LRUCache) getCache() {
	for n := l.head; n != nil; n = n.next {
		fmt.Println(n.Key, n.Value)
	}
}
func main() {
	cache := Constructor(3)
	cache.Put(11, 1)
	cache.Put(22, 2)
	cache.Put(33, 3)
	cache.Put(44, 4)
	fmt.Println("before")
	cache.getCache()
	v := cache.Get(33)
	fmt.Println("after get", v)
	cache.getCache()
}

实现2

https://leetcode-cn.com/problems/lru-cache/solution/man-hua-ceng-ceng-fen-xi-lrukan-bu-dong-wo-chi-shi/

实现3

采用双向链表,标准库container/list提供了双向链表
利用map对链表节点进行索引
记录缓存大小

https://leetcode-cn.com/problems/lru-cache/solution/lru-go-jie-fa-by-shi-xiao-shi/

官方库: https://github.com/bluele/gcache/blob/master/lru.go

posted @ 2020-03-23 20:26  sicnu-yudidi  阅读(158)  评论(0编辑  收藏  举报