【算法】LRU缓存机制

本文介绍了如何使用数据结构实现LRU缓存机制。方法一是通过维护两个字典,一个用于存储key-value,另一个记录key的时间戳,当缓存满时删除最久未使用的key。方法二是利用双向链表和字典,实现O(1)时间复杂度的get和put操作。两种方法都确保了在缓存容量限制下,最近最少使用的数据会被淘汰。
摘要由CSDN通过智能技术生成
题目

运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制 。
实现 LRUCache 类:

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

进阶:你是否可以在 O ( 1 ) O(1) O(1) 时间复杂度内完成这两种操作?

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/lru-cache
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解分析
  1. 缓存容量限制
  2. 达到容量删除最久未使用的key和value,

方法一:维护两个字典表,一个是key-value,另一个是key-time。其中:get()和put()的复杂度为 O ( c a p a c i t y ) O(capacity) O(capacity)

class LRUCache:
	
	def __init__(self, capacity):
		self.capacity = capacity
		# cache dict
		self.cache = {} 
		# time dict
		self.times = {}
	
	def get(self, key):
		# not exist return -1
		if key not in self.cache.keys():
			return -1
		# add one time for all keys
		for k, t in self.times.items():
			self.times[k] = t + 1
		# set the key operated zero time
		self.times[key] = 0
		return self.cache[key]
	
	def put(self, key, value):
		# if key in the cache, change the value of key
		if key in self.cache.keys():
			for k, t in self.times.items():
				self.times[k] = t + 1
			self.cache[key] = value
			self.times[key] = 0
		else:
			# if capacity not full
			if self.capacity > len(self.cache):
				for k, t in self.times.items():
					self.times[k] = t + 1
				self.cache[key] = value
				self.times[key] = 0
			else:  # if capacity full, delete the key of max times 
				k,t = None, None 
				for m, n in self.times.items():
					if k is None:
						k = m
						t = n
					else:
						if n > t:
							k = m
							t = n
				self.cache.pop(k)
				self.times.pop(k)
				for k, t in self.times.items():
					self.times[k] = t + 1
				self.cache[key] = value
				self.times[key] = 0				

方法二:维护一个cache字典和一个双向链表,其中get()和put()的时间复杂度为 O ( 1 ) O(1) O(1)

# define double link
class DLinkedNode:
	def __init__(self, key=None, value=None, prev=None, next=None):
		self.key = key
		self.value = value
		self.prev = prev
		self.next = next

class LRUCache:
	
	def __init__(self, capacity):
		self.capacity = capacity
		self.cache = {}
		self.head = DLinkedNode()
		self.tail = DLinkedNode()
		self.head.next = self.tail
		self.tail.prev = self.head
	
	def get(self, key):
		if key not in self.cache.keys():
			return -1
		self.remove(self.cache[key])
		self.addNode(self.cache[key])
		return self.cache[key].value
	
	def put(self, key, value):
		if key in self.cache.keys():
			node = self.cache[key]
			node.value = value
			self.remove(node)
			self.addNode(node)
		else:
			if self.capacity > len(self.cache):
				node = DLinkedNode(key=key, value=value)
				self.addNode(node)
				self.cache[key] = node
			else:
				self.cache.pop(self.removeTail().key)
				node = DLinkedNode(key=key, value=value)
				self.addNode(node)
				self.cache[key] = node

	def addNode(self, node):
		node.prev = self.head
		node.next = self.head.next
		self.head.next.prev = node
		self.head.next = node
	def remove(self, node):
		node.prev.next = node.next
		node.next.prev = node.prev
	def removeTail(self):
		node = self.tail.prev
		self.remove(node)
		return node
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值