当前位置:网站首页>Leetcode 146. LRU 缓存
Leetcode 146. LRU 缓存
2022-07-04 07:41:00 【von Libniz】
题目描述
请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。
实现 LRUCache 类:
LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存
int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 。
void put(int key, int value) 如果关键字 key 已经存在,则变更其数据值 value ;如果不存在,则向缓存中插入该组 key-value 。如果插入操作导致关键字数量超过 capacity ,则应该 逐出 最久未使用的关键字。
函数 get 和 put 必须以 O(1) 的平均时间复杂度运行。
输入
["LRUCache", "put", "put", "get", "put", "get", "put", "get", "get", "get"]
[[2], [1, 1], [2, 2], [1], [3, 3], [2], [4, 4], [1], [3], [4]]
输出
[null, null, null, 1, null, -1, null, -1, 3, 4]
解释
LRUCache lRUCache = new LRUCache(2);
lRUCache.put(1, 1); // 缓存是 {
1=1}
lRUCache.put(2, 2); // 缓存是 {
1=1, 2=2}
lRUCache.get(1); // 返回 1
lRUCache.put(3, 3); // 该操作会使得关键字 2 作废,缓存是 {
1=1, 3=3}
lRUCache.get(2); // 返回 -1 (未找到)
lRUCache.put(4, 4); // 该操作会使得关键字 1 作废,缓存是 {
4=4, 3=3}
lRUCache.get(1); // 返回 -1 (未找到)
lRUCache.get(3); // 返回 3
解法一:哈希表+链表
这题和数据流之类的题目一样,都是一个套路:用链表来记录数据顺序,用哈希表快速找到链表节点,再根据需求移动节点位置。这里用一个单向链表来实现,哈希表存储key对应value节点的前一个节点。当然也可以直接用双向链表。
class ListNode:
def __init__(self, key, value, next=None):
self.key = key
self.value = value
self.next = next
class LRUCache:
"""解法1:HashMap + LinkedList"""
def __init__(self, capacity: int):
self.dummy = ListNode(-1, -1)
self.tail = self.dummy
self.key_to_prev = {
}
self.capacity = capacity
def get(self, key: int) -> int:
if key not in self.key_to_prev:
return -1
self.remove_to_last(key)
return self.key_to_prev.get(key).next.value
def put(self, key: int, value: int) -> None:
if key in self.key_to_prev:
self.remove_to_last(key)
self.tail.value = value
return
if len(self.key_to_prev) < self.capacity:
self.add_key_value(key, value)
return
# not enough capacity
self.remove_lru()
self.add_key_value(key, value)
def set_value(self, key, value):
pre_node = self.key_to_prev.get(key)
target_node = pre_node.next
target_node.value = value
def add_key_value(self, key, value):
new_node = ListNode(key, value)
self.key_to_prev[key] = self.tail # s
self.tail.next = new_node
self.tail = new_node
def remove_lru(self):
remove_target = self.dummy.next
self.key_to_prev.pop(remove_target.key)
self.dummy.next = remove_target.next
# capacity 可能为1,所以还是要判断target.next是否为空
if remove_target == self.tail:
self.tail = self.dummy
else:
self.key_to_prev[remove_target.next.key] = self.dummy
def remove_to_last(self, key):
pre = self.key_to_prev[key]
target = pre.next
if self.tail == target:
return
pre.next = target.next
self.key_to_prev[target.next.key] = pre
target.next = None
self.tail.next = target
self.key_to_prev[key] = self.tail
self.tail = target
解法二:OrderedDict
直接使用内置的数据结构:OrderedDict。
class LRUCache:
""" 解法2:OrderedDict """
def __init__(self, capacity: int):
self.cache = OrderedDict()
self.capacity = capacity
def get(self, key: int) -> int:
if key not in self.cache:
return -1
value = self.cache.pop(key) # 访问了, 先删除
self.cache[key] = value # 再加到最后
return value
def put(self, key: int, value: int) -> None:
if key in self.cache:
self.cache.pop(key) # 先删除
self.cache[key] = value # 再加到最后
if len(self.cache) > self.capacity:
self.cache.popitem(last=False)
边栏推荐
- Life planning (flag)
- Would you like to go? Go! Don't hesitate if you like it
- socket inet_ pton() inet_ Ntop() function (a new network address translation function, which converts the expression format and numerical format to each other. The old ones are inet_aton(), INET_ ntoa
- MySQL error resolution - error 1261 (01000): row 1 doesn't contain data for all columns
- L1-021 important words three times (5 points)
- 【FreeRTOS】FreeRTOS学习笔记(7)— 手写FreeRTOS双向链表/源码分析
- [Gurobi] 简单模型的建立
- Rhcsa the next day
- There is no Chinese prompt below when inputting text in win10 Microsoft Pinyin input method
- Advanced MySQL: Basics (5-8 Lectures)
猜你喜欢

ZABBIX monitoring system custom monitoring content
![[C language] open the door of C](/img/e0/2f107966423d6492c39995c77a445e.jpg)
[C language] open the door of C

PCIe knowledge points -010: where to get PCIe hot plug data

Project 1 household accounting software (goal + demand description + code explanation + basic fund and revenue and expenditure details record + realization of keyboard access)

Experience installing VMware esxi 6.7 under VMware Workstation 16

Advanced MySQL: Basics (5-8 Lectures)

如何用MOS管来实现电源防反接电路

Unity opens the explorer from the inspector interface, selects and records the file path

Blog stop statement

Zephyr learning notes 1, threads
随机推荐
Text processing function sorting in mysql, quick search of collection
tornado之目录
tornado项目之路由装饰器
PCIE知识点-010:PCIE 热插拔资料从哪获取
【FreeRTOS】FreeRTOS學習筆記(7)— 手寫FreeRTOS雙向鏈錶/源碼分析
User login function: simple but difficult
Improve the accuracy of 3D reconstruction of complex scenes | segmentation of UAV Remote Sensing Images Based on paddleseg
Routing decorator of tornado project
[FreeRTOS] FreeRTOS learning notes (7) - handwritten FreeRTOS two-way linked list / source code analysis
Advanced MySQL: Basics (5-8 Lectures)
Types of references in BibTex
window上用.bat文件启动项目
Book list | as the technical support Party of the Winter Olympics, Alibaba cloud's technology is written in these books!
Handwritten easy version flexible JS and source code analysis
Linear algebra 1.1
[untitled] notice on holding "2022 traditional fermented food and modern brewing technology"
Used on windows Bat file startup project
谷歌官方回应:我们没有放弃TensorFlow,未来与JAX并肩发展
The IP bound to the socket is inaddr_ The meaning of any htonl (inaddr_any) (0.0.0.0 all addresses, uncertain addresses, arbitrary addresses)
MySQL 数据库 - 函数 约束 多表查询 事务