학습 노트 | LeetCode 460. LFU 캐 시
가장 자주 사용 되 지 않 는 (LFU) 캐 시 알고리즘 을 위해 데이터 구 조 를 설계 하고 구현 하 십시오.다음 동작 을 지원 해 야 합 니 다: get 과 put.
get(key)
- 키 가 캐 시 에 존재 하면 키 의 값 (항상 정수) 을 가 져 옵 니 다. 그렇지 않 으 면 - 1 을 되 돌려 줍 니 다.put(key, value)
- 키 가 존재 하면 값 을 변경 합 니 다.키 가 존재 하지 않 는 다 면 키 쌍 을 삽입 하 십시오.캐 시가 용량 에 도 달 했 을 때 새 항목 을 삽입 하기 전에 가장 자주 사용 하지 않 는 항목 을 무효 로 해 야 합 니 다.이 문제 에서 무승부 (즉, 두 개 이상 의 키 가 같은 사용 주파 수 를 가지 고 있 음) 가 존재 할 때 가장 오래 사용 하지 않 은 키 를 제거 해 야 한다.get
과 put
함수 의 횟수 의 합 이다.사용 횟수 는 해당 항목 이 제거 되면 0 으로 설 정 됩 니 다.진급:
예시:
LFUCache cache = new LFUCache( 2 /* capacity ( ) */ );
cache.put(1, 1);
cache.put(2, 2);
cache.get(1); // 1
cache.put(3, 3); // key 2
cache.get(2); // -1 ( key 2)
cache.get(3); // 3
cache.put(4, 4); // key 1
cache.get(1); // -1 ( key 1)
cache.get(3); // 3
cache.get(4); // 4
코드
class Node:
def __init__(self, key, val, freq=1, prev=None, next=None):
self.key = key
self.val = val
self.freq = freq
self.prev = prev
self.next = next
class LinkedNodeList:
def __init__(self):
self.head = None
self.tail = None
self.size = 0
def __len__(self):
return self.size
def append(self, node):
if self.head is None and self.tail is None:
self.head = self.tail = node
else:
self.tail.next = node
node.prev = self.tail
self.tail = node
self.size += 1
def remove(self, node):
assert len(self) >= 1
if node is self.head and node is self.tail:
self.head = None
self.tail = None
else:
if node is self.head:
self.head = node.next
node.next = None
elif node is self.tail:
self.tail = node.prev
node.prev = None
else:
prev = node.prev
next = node.next
prev.next = next
next.prev = prev
node.prev = None
node.next = None
self.size -= 1
class LFUCache(object):
def __init__(self, capacity):
"""
:type capacity: int
"""
self.heap = []
self.capacity = capacity
self.cnt = 0
self.freq_mapping = {}
self.key_mapping = {}
@property
def min_freq(self):
return min(self.freq_mapping.keys())
def _get_existing_node(self, key):
node = self.key_mapping[key]
old_freq = node.freq
new_freq = old_freq + 1
linked_list = self.freq_mapping[old_freq]
linked_list.remove(node)
if len(linked_list) == 0:
self.freq_mapping.pop(old_freq, None)
linked_list = self.freq_mapping.get(new_freq, None) or LinkedNodeList()
node.freq = new_freq
linked_list.append(node)
self.freq_mapping[new_freq] = linked_list
return node
def _put_new_node(self, key, value):
linked_list = self.freq_mapping.get(1, None) or LinkedNodeList()
node = Node(key, value)
self.key_mapping[key] = node
linked_list.append(node)
self.freq_mapping[1] = linked_list
self.cnt += 1
def get(self, key):
"""
:type key: int
:rtype: int
"""
val = -1
if key in self.key_mapping:
node = self._get_existing_node(key)
val = node.val
return val
def put(self, key, value):
"""
:type key: int
:type value: int
:rtype: None
"""
if self.capacity == 0:
return
if key in self.key_mapping:
node = self._get_existing_node(key)
node.val = value
else:
if self.cnt < self.capacity:
self._put_new_node(key, value)
else:
min_freq = self.min_freq
linked_list = self.freq_mapping[min_freq]
head = linked_list.head
self.key_mapping.pop(head.key)
linked_list.remove(head)
del head
if len(linked_list) == 0:
self.freq_mapping.pop(min_freq)
self._put_new_node(key, value)
# Your LFUCache object will be instantiated and called as such:
# obj = LFUCache(capacity)
# param_1 = obj.get(key)
# obj.put(key,value)
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Rails Turbolinks를 페이지 단위로 비활성화하는 방법원래 Turobolinks란? Turbolinks는 링크를 생성하는 요소인 a 요소의 클릭을 후크로 하고, 이동한 페이지를 Ajax에서 가져옵니다. 그 후, 취득 페이지의 데이터가 천이 전의 페이지와 동일한 것이 있...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.