LeetCode 460. LFU cache (hash doubly linked list)

1. Topic

Design and implement the least frequently used (LFU) cache data structure. It should support the following operations: get and put.

  • get(key) - If the key exists in the cache, then get the value (always positive) key, otherwise -1.
  • put(key, value) - if the key does not exist, or insert set value.
  • When the cache reaches its capacity, it should be in before inserting a new project, the project is not the most frequently used is invalid.
  • In this problem, when there is a tie (i.e., two or more keys having the same frequency), the least recently used key is removed.

Advanced:
you can (1) O performs two operations within the time complexity?

示例:
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

Source: stay button (LeetCode)
link: https: //leetcode-cn.com/problems/lfu-cache
copyrighted by deduction from all networks. Commercial reprint please contact the authorized official, non-commercial reprint please indicate the source.

2. Problem Solving

class node{
public:
	int k, v, f;
	node(int key, int val, int freq):k(key),v(val),f(freq){}
};

class LFUCache {
	unordered_map<int, list<node>::iterator> kPos;//key 对应的节点迭代器位置
    unordered_map<int, list<node>> freq_list;//不同的频数下挂着一条双链表,尾部是最少使用的
    int cap;
    int minfreq;
    int size;
public:
    LFUCache(int capacity) {
    	cap = capacity;
    	minfreq = 0;
    	size = 0;
    }
    
    int get(int key) {
    	if(kPos.find(key)==kPos.end())
    		return -1;
    	auto it = kPos[key];
    	int f = it->f;
    	int v = it->v;
    	if(f == minfreq && freq_list[f].size() == 1)
    		minfreq++;
    	freq_list[f].erase(it);
    	freq_list[++f].push_front(node(key,v,f));
    	kPos[key] = freq_list[f].begin();
    	return v;
    }
    
    void put(int key, int value) {
    	if(kPos.find(key)!=kPos.end())
    	{
    		auto it = kPos[key];
			int f = it->f;
			if(f == minfreq && freq_list[f].size()==1)
				minfreq++;
			freq_list[f].erase(it);
			freq_list[++f].push_front(node(key,value,f));
			kPos[key] = freq_list[f].begin();
    	}
    	else if(size < cap)
    	{
			minfreq = 1;
			freq_list[minfreq].push_front(node(key,value,1));
			kPos[key] = freq_list[1].begin();
			size++;
    	}
    	else if(cap != 0 && size == cap)
    	{
    		auto Node = freq_list[minfreq].back();
    		int k = Node.k;
    		freq_list[minfreq].pop_back();
    		kPos.erase(k);
    		size--;
    		put(key, value);
    	}
    }
};

228 ms 40 MB

Published 815 original articles · won praise 1650 · Views 390,000 +

Guess you like

Origin blog.csdn.net/qq_21201267/article/details/105336389