-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy path146.lru缓存机制.py
144 lines (119 loc) · 3.7 KB
/
146.lru缓存机制.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#
# @lc app=leetcode.cn id=146 lang=python3
#
# [146] LRU缓存机制
#
# https://leetcode-cn.com/problems/lru-cache/description/
#
# algorithms
# Medium (44.69%)
# Likes: 373
# Dislikes: 0
# Total Accepted: 29.5K
# Total Submissions: 65.5K
# Testcase Example: '["LRUCache","put","put","get","put","get","put","get","get","get"]\n[[2],[1,1],[2,2],[1],[3,3],[2],[4,4],[1],[3],[4]]'
#
# 运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制。它应该支持以下操作: 获取数据 get 和 写入数据 put 。
#
# 获取数据 get(key) - 如果密钥 (key) 存在于缓存中,则获取密钥的值(总是正数),否则返回 -1。
# 写入数据 put(key, value) -
# 如果密钥不存在,则写入其数据值。当缓存容量达到上限时,它应该在写入新数据之前删除最近最少使用的数据值,从而为新的数据值留出空间。
#
# 进阶:
#
# 你是否可以在 O(1) 时间复杂度内完成这两种操作?
#
# 示例:
#
# LRUCache cache = new LRUCache( 2 /* 缓存容量 */ );
#
# cache.put(1, 1);
# cache.put(2, 2);
# cache.get(1); // 返回 1
# cache.put(3, 3); // 该操作会使得密钥 2 作废
# cache.get(2); // 返回 -1 (未找到)
# cache.put(4, 4); // 该操作会使得密钥 1 作废
# cache.get(1); // 返回 -1 (未找到)
# cache.get(3); // 返回 3
# cache.get(4); // 返回 4
#
#
#
# @lc code=start
from collections import OrderedDict
class LRUCache(OrderedDict):
# OrderedDict 实现
def __init__(self, capacity: int):
self.capacity = capacity
def get(self, key: int) -> int:
if key not in self:
return -1
self.move_to_end(key)
return self[key]
def put(self, key: int, value: int) -> None:
if key in self:
self.move_to_end(key)
self[key] = value
if len(self) > self.capacity:
self.popitem(last=False)
# Your LRUCache object will be instantiated and called as such:
# obj = LRUCache(capacity)
# param_1 = obj.get(key)
# obj.put(key,value)
# @lc code=end
class DLinkedNode():
def __init__(self):
self.key = 0
self.value = 0
self.prev = None
self.next = None
class LRUCache2():
"""
基于哈希表+双向链表
"""
def _add_node(self, node):
node.prev = self.head
node.next = self.head.next
self.head.next.prev = node
self.head.next = node
def _remove_node(self, node):
prev = node.prev
new = node.next
prev.next = new
new.prev = prev
def _move_to_head(self, node):
self._remove_node(node)
self._add_node(node)
def _pop_tail(self):
res = self.tail.prev
self._remove_node(res)
return res
def __init__(self, capacity):
self.cache = {}
self.size = 0
self.capacity = capacity
self.head, self.tail = DLinkedNode(), DLinkedNode()
self.head.next = self.tail
self.tail.prev = self.head
def get(self, key):
node = self.cache.get(key, None)
if not node:
return -1
self._move_to_head(node)
return node.value
def put(self, key, value):
node = self.cache.get(key, None)
if not node:
newNode = DLinkedNode()
newNode.key = key
newNode.value = value
self.cache[key] = newNode
self._add_node(newNode)
self.size += 1
if self.size > self.capacity:
tail = self._pop_tail()
del self.cache[tail.key]
self.size -= 1
else:
node.value = value
self._move_to_head(node)