题目:
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
思路:
定义一个结构体来表示cache中的数据的key-value和使用频率:
typedef struct Node{ //使用typedef将数据类型struct Node重命名为Node
int key;
int value;
int frequency;
Node(int k,int v,int f){ //结构体构造函数
key = k;
value = v;
frequency = f;
}
}Node;
使用动态数组来保存cache中的数据,执行put时,分为三种情况:1、key不存在且内存够时,2、key不存在内存不够时,3、key存在时。
第一种情况时直接将这个数据加到数组最后,第二种情况时要删除使用频率少且最近最不使用的,第三种情况要修改数据的频率。注意put时,三种情况下都要将这个数据放在数组最后。get方法注意get后要增加频率并把对应的数据删除再放到数组最后。
注意边界条件:capacity == 0时,直接 return
代码:
#include<iostream>
#include<string.h>
#include<vector>
using namespace std;
class FLUCache{
#define MAX 99999999
public:
typedef struct Node{
int key;
int value;
int frequency;
Node(int k,int v,int f){
key = k;
value = v;
frequency = f;
}
}Node;
vector<Node> recent;
int capacity;
int size;
FLUCache(int c){
capacity = c;
size = 0;
}
//获取cache中的数据的value
int get(int key){
int index = findKey(key);
if(index != -1){
int curFrequency = recent.at(index).frequency;
int value = recent.at(index).value;
recent.erase(recent.begin()+index);
recent.push_back(Node(key,value,++curFrequency));
return value;
}else{
return -1;
}
}
//向cache中放数据
void put(int key,int value){
if(capacity == 0) return;
int index = findKey(key);
//key不存在切容量未满
if(index == -1 && size < capacity){
recent.push_back(Node(key,value,1));
size++;
}else if(index == -1 && size == capacity){ //key不存在,容量满
int index = findLeastFrequencyAndUsed();
//删除最少频率和最近不使用的
recent.erase(recent.begin()+index);
recent.push_back(Node(key,value,1));
}else if(index != -1){ //key存在
int curFrequency = recent.at(index).frequency;
recent.erase(recent.begin()+index);
recent.push_back(Node(key,value,++curFrequency));
}
}
//获取查找数据的数组中的索引
int findKey(int key){
int i;
for(i = 0; i < recent.size(); i++){
struct Node node = recent.at(i);
if(key == node.key){
return i;
}
}
return -1;
}
//查找需要驱逐的数据在数组中的索引
int findLeastFrequencyAndUsed(){
int i,index;
index = 0;
int minFrequency = MAX;
for(i = 0; i < recent.size(); i++){
Node node = recent.at(i);
if(node.frequency < minFrequency){
minFrequency = node.frequency;
index = i;
}
}
return index;
}
};
int main(){
FLUCache *cache = new FLUCache(2);
cache->put(1,1);
cache->put(2, 2);
cout<<cache->get(1)<<endl; // returns 1
cache->put(3, 3); // evicts key 2
cout<<cache->get(2)<<endl; // returns -1 (not found)
cout<<cache->get(3)<<endl; // returns 3.
cache->put(4, 4); // evicts key 1.
cout<<cache->get(1)<<endl; // returns -1 (not found)
cout<<cache->get(3)<<endl; // returns 3
cout<<cache->get(4)<<endl; // returns 4
return 0;
}