zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    树世界
    清空 NumericUpDown
    没有评论的日子
    GetData.cs

    Hashtable 在程序中控制重复项
    Convert.ToInt32() VS System.Int32.Parse()
    饮食九要素
    添加 or 修改 的一个处理方式
    一个关于 电话号码 的正则表达式
  • 原文地址:https://www.cnblogs.com/yudidi/p/12553920.html
Copyright © 2011-2022 走看看