460.LFU-cache-cn

题目地址

Problem

题目描述

Design and implement a data structure for Least Frequently Used (LFU) cache. It should support the following operations: get and put.

get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.
put(key, value) - Set or insert the value if the key is not already present. When the cache reaches its capacity, it should invalidate the least frequently used item before inserting a new item. For the purpose of this problem, when there is a tie (i.e., two or more keys that have the same frequency), the least recently used key would be evicted.

Follow up:
Could you do both operations in O(1) time complexity?

Example:

LFUCache cache = new LFUCache( 2 /* capacity */ );

cache.put(1, 1);
cache.put(2, 2);
cache.get(1);       // returns 1
cache.put(3, 3);    // evicts key 2
cache.get(2);       // returns -1 (not found)
cache.get(3);       // returns 3.
cache.put(4, 4);    // evicts key 1.
cache.get(1);       // returns -1 (not found)
cache.get(3);       // returns 3
cache.get(4);       // returns 4

思路

LFU(Least frequently used) 但内存容量满的情况下,有新的数据进来,需要更多空间的时候,就需要删除被访问频率最少的元素。

举个例子,比如说cache容量是 3,按顺序依次放入 1,2,1,2,1,3, cache已存满 3 个元素 (1,2,3), 这时如果想放入一个新的元素 4 的时候,就需要腾出一个元素空间。 用 LFU,这里就淘汰 3, 因为 3 的次数只出现依次, 1 和 2 出现的次数都比 3 多。

题中 getput 都是 O(1)的时间复杂度,那么删除和增加都是O(1),可以想到用双链表,和HashMap,用一个HashMap, nodeMap, 保存当前key,和 node{key, value, frequent}的映射。 这样get(key)的操作就是O(1). 如果要删除一个元素,那么就需要另一个HashMap,freqMap,保存元素出现次数(frequent)和双链表(DoublyLinkedlist) 映射, 这里双链表存的是frequent相同的元素。每次getput的时候,frequent+1,然后把node插入到双链表的head node, head.next=node 每次删除freqent最小的双链表的tail node, tail.prev

用给的例子举例说明:

460.lfu-cache-1
460.lfu-cache-2
460.lfu-cache-3
460.lfu-cache-4
460.lfu-cache-5
460.lfu-cache-6
460.lfu-cache-7
460.lfu-cache-8

关键点分析

用两个Map分别保存 nodeMap {key, node}freqMap{frequent, DoublyLinkedList}。 实现getput操作都是O(1)的时间复杂度。

可以用Java自带的一些数据结构,比如HashLinkedHashSet,这样就不需要自己自建Node,DoublelyLinkedList。 可以很大程度的缩减代码量。

代码(Java code)

参考(References)

Last updated

Was this helpful?