LFU(Least Frequently Used)算法,即最少使用算法,是操作系统中常用的一种页面置换算法。它根据页面被访问的频率来决定是否置换。本文将深入解析LFU算法,并通过经典例题帮助读者轻松应对相关考试和面试。
LFU算法原理
LFU算法的基本思想是:如果一个页面很少被访问,那么它很可能在未来也不会被访问,因此可以将其置换出内存。具体来说,LFU算法将页面按照访问频率进行排序,并将最少的那个页面置换出内存。
LFU算法实现
以下是一个简单的LFU算法实现示例,使用Python语言:
class LFUCache:
def __init__(self, capacity: int):
self.capacity = capacity
self.cache = {}
self.min_freq = 0
self.freq_map = {}
def get(self, key: int) -> int:
if key not in self.cache:
return -1
self._update(key)
return self.cache[key]
def put(self, key: int, value: int) -> None:
if self.capacity <= 0:
return
if key in self.cache:
self.cache[key] = value
self._update(key)
else:
if len(self.cache) == self.capacity:
self._evict()
self.cache[key] = value
self.freq_map[1] = self.freq_map.get(1, 0) + 1
self.min_freq = 1
def _update(self, key: int) -> None:
old_freq = self.cache[key]
new_freq = old_freq + 1
if old_freq == self.min_freq and len(self.freq_map) == self.min_freq:
self.min_freq += 1
self.freq_map[old_freq] -= 1
if self.freq_map[old_freq] == 0:
del self.freq_map[old_freq]
self.freq_map[new_freq] = self.freq_map.get(new_freq, 0) + 1
self.cache[key] = value
def _evict(self) -> None:
key_to_evict = min(self.freq_map[self.min_freq], key=lambda x: self.cache[x])
del self.cache[key_to_evict]
self.freq_map[self.min_freq] -= 1
if self.freq_map[self.min_freq] == 0:
del self.freq_map[self.min_freq]
经典例题解析
例题1:给定一个缓存容量为2的LFU缓存,请实现一个方法来模拟该缓存的行为,并返回缓存中所有键值对。
class LFUCache:
def __init__(self, capacity: int):
self.capacity = capacity
self.cache = {}
self.min_freq = 0
self.freq_map = {}
def get(self, key: int) -> int:
if key not in self.cache:
return -1
self._update(key)
return self.cache[key]
def put(self, key: int, value: int) -> None:
if self.capacity <= 0:
return
if key in self.cache:
self.cache[key] = value
self._update(key)
else:
if len(self.cache) == self.capacity:
self._evict()
self.cache[key] = value
self.freq_map[1] = self.freq_map.get(1, 0) + 1
self.min_freq = 1
def _update(self, key: int) -> None:
old_freq = self.cache[key]
new_freq = old_freq + 1
if old_freq == self.min_freq and len(self.freq_map) == self.min_freq:
self.min_freq += 1
self.freq_map[old_freq] -= 1
if self.freq_map[old_freq] == 0:
del self.freq_map[old_freq]
self.freq_map[new_freq] = self.freq_map.get(new_freq, 0) + 1
self.cache[key] = value
def _evict(self) -> None:
key_to_evict = min(self.freq_map[self.min_freq], key=lambda x: self.cache[x])
del self.cache[key_to_evict]
self.freq_map[self.min_freq] -= 1
if self.freq_map[self.min_freq] == 0:
del self.freq_map[self.min_freq]
# 测试代码
lfu_cache = LFUCache(2)
lfu_cache.put(1, 1)
lfu_cache.put(2, 2)
print(lfu_cache.get(1)) # 输出 1
lfu_cache.put(3, 3)
print(lfu_cache.get(2)) # 输出 -1
print(lfu_cache.get(3)) # 输出 3
lfu_cache.put(4, 4)
print(lfu_cache.get(1)) # 输出 -1
print(lfu_cache.get(3)) # 输出 3
print(lfu_cache.get(4)) # 输出 4
例题2:给定一个包含多个操作(如get、put)的序列,请实现一个方法来模拟LFU缓存的行为,并返回每个操作的结果。
class LFUCache:
def __init__(self, capacity: int):
self.capacity = capacity
self.cache = {}
self.min_freq = 0
self.freq_map = {}
def get(self, key: int) -> int:
if key not in self.cache:
return -1
self._update(key)
return self.cache[key]
def put(self, key: int, value: int) -> None:
if self.capacity <= 0:
return
if key in self.cache:
self.cache[key] = value
self._update(key)
else:
if len(self.cache) == self.capacity:
self._evict()
self.cache[key] = value
self.freq_map[1] = self.freq_map.get(1, 0) + 1
self.min_freq = 1
def _update(self, key: int) -> None:
old_freq = self.cache[key]
new_freq = old_freq + 1
if old_freq == self.min_freq and len(self.freq_map) == self.min_freq:
self.min_freq += 1
self.freq_map[old_freq] -= 1
if self.freq_map[old_freq] == 0:
del self.freq_map[old_freq]
self.freq_map[new_freq] = self.freq_map.get(new_freq, 0) + 1
self.cache[key] = value
def _evict(self) -> None:
key_to_evict = min(self.freq_map[self.min_freq], key=lambda x: self.cache[x])
del self.cache[key_to_evict]
self.freq_map[self.min_freq] -= 1
if self.freq_map[self.min_freq] == 0:
del self.freq_map[self.min_freq]
# 测试代码
lfu_cache = LFUCache(2)
operations = [
(1, 1),
(2, 2),
(1),
(3, 3),
(2),
(4, 4),
(1),
(3),
(4)
]
results = []
for op in operations:
if op[0] == 1:
results.append(lfu_cache.get(op[1]))
elif op[0] == 2:
lfu_cache.put(op[1], op[2])
print(results) # 输出 [1, -1, 3, -1, 4, -1, 3, -1, 4]
总结
通过本文的介绍,相信读者已经对LFU算法有了深入的了解。通过经典例题的解析,读者可以轻松应对相关考试和面试。希望本文对读者有所帮助!
