当前位置:网站首页>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)
边栏推荐
- 博客停更声明
- L1-025 positive integer a+b (15 points)
- 果果带你写链表,小学生看了都说好
- It's healthy to drink medicinal wine like this. Are you drinking it right
- Thesis learning -- time series similarity query method based on extreme point characteristics
- Enter the year, month, and determine the number of days
- L1-023 output gplt (20 points)
- How to send mail with Jianmu Ci
- L1-021 important words three times (5 points)
- 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)
猜你喜欢
Improve the accuracy of 3D reconstruction of complex scenes | segmentation of UAV Remote Sensing Images Based on paddleseg
Advanced MySQL: Basics (5-8 Lectures)
This monitoring system can monitor the turnover intention and fishing all, and the product page has 404 after the dispute appears
There is no Chinese prompt below when inputting text in win10 Microsoft Pinyin input method
Go learning notes - constants
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)
Zephyr study notes 2, scheduling
论文学习——基于极值点特征的时间序列相似性查询方法
Two years ago, the United States was reluctant to sell chips, but now there are mountains of chips begging China for help
Easy to understand: understand the time series database incluxdb
随机推荐
【FreeRTOS】FreeRTOS学习笔记(7)— 手写FreeRTOS双向链表/源码分析
Activiti常见操作数据表关系
深入浅出:了解时序数据库 InfluxDB
Handwritten easy version flexible JS and source code analysis
[Gurobi] 简单模型的建立
Relations courantes de la fiche de données d'exploitation pour les activités
大厂技术专家:架构设计中常用的思维模型
How to write a summary of the work to promote the implementation of OKR?
促进OKR落地的工作总结该如何写?
21个战略性目标实例,推动你的公司快速发展
Zephyr study notes 2, scheduling
L1-026 I love gplt (5 points)
How to reset IntelliSense in vs Code- How to reset intellisense in VS Code?
I was pressed for the draft, so let's talk about how long links can be as efficient as short links in the development of mobile terminals
Xcode 14之大变化详细介绍
It's healthy to drink medicinal wine like this. Are you drinking it right
Amd RX 7000 Series graphics card product line exposure: two generations of core and process mix and match
Life planning (flag)
Système de surveillance zabbix contenu de surveillance personnalisé
L1-025 positive integer a+b (15 points)