lfu-cache(需要O(1),所以挺难的)
https://leetcode.com/problems/lfu-cache/
很难,看了下面的参考:
https://discuss.leetcode.com/topic/69137/java-o-1-accept-solution-using-hashmap-doublelinkedlist-and-linkedhashset
注意其中的思想就是如下所述:
Your idea is brilliant... Especially storing all keys with same counts in one node, if one of the keys in that node got hit once more,
it will be moved into a new node with (count+1) if the node exits or it will be wrapped into a newly created node with
(count+1).
All your operations are guaranteed O(1) no doubt. There is no way to complete it bug-free within half an hour. So in the real interview,
I might as well explain the idea and how we should implement all operations in each scenario,
instead of actually trying to complete whole program...
Anyway, thank you so much for your time and explanation.
并且注意,用到了LinkedHashSet的特性,就是虽然是Set,但是是按照顺序插入的方式来遍历的。
public class LFUCache {
private Node head = null;
private int cap = 0;
private HashMap<Integer, Integer> valueHash = null;
private HashMap<Integer, Node> nodeHash = null;
public LFUCache(int capacity) {
this.cap = capacity;
valueHash = new HashMap<Integer, Integer>();
nodeHash = new HashMap<Integer, Node>();
}
public int get(int key) {
if (valueHash.containsKey(key)) {
increaseCount(key);
return valueHash.get(key);
}
return -1;
}
public void set(int key, int value) {
if ( cap == 0 ) return;
if (valueHash.containsKey(key)) {
valueHash.put(key, value);
Node node = nodeHash.get(key);
node.keys.remove(key);
node.keys.add(key);
} else {
if (valueHash.size() < cap) {
valueHash.put(key, value);
} else {
removeOld();
valueHash.put(key, value);
}
addToHead(key);
}
increaseCount(key);
}
private void addToHead(int key) {
if (head == null) {
head = new Node(0);
head.keys.add(key);
} else if (head.count > 0) {
Node node = new Node(0);
node.keys.add(key);
node.next = head;
head.prev = node;
head = node;
} else {
head.keys.add(key);
}
nodeHash.put(key, head);
}
private void increaseCount(int key) {
Node node = nodeHash.get(key);
node.keys.remove(key);
if (node.next == null) {
node.next = new Node(node.count+1);
node.next.prev = node;
node.next.keys.add(key);
} else if (node.next.count == node.count+1) {
node.next.keys.add(key);
} else {
Node tmp = new Node(node.count+1);
tmp.keys.add(key);
tmp.prev = node;
tmp.next = node.next;
node.next.prev = tmp;
node.next = tmp;
}
nodeHash.put(key, node.next);
if (node.keys.size() == 0) remove(node);
}
private void removeOld() {
if (head == null) return;
int old = 0;
for (int n: head.keys) {
old = n;
break;
}
head.keys.remove(old);
if (head.keys.size() == 0) remove(head);
nodeHash.remove(old);
valueHash.remove(old);
}
private void remove(Node node) {
if (node.prev == null) {
head = node.next;
} else {
node.prev.next = node.next;
}
if (node.next != null) {
node.next.prev = node.prev;
}
}
class Node {
public int count = 0;
public LinkedHashSet<Integer> keys = null;
public Node prev = null, next = null;
public Node(int count) {
this.count = count;
keys = new LinkedHashSet<Integer>();
prev = next = null;
}
}
}
/**
* Your LFUCache object will be instantiated and called as such:
* LFUCache obj = new LFUCache(capacity);
* int param_1 = obj.get(key);
* obj.set(key,value);
*/
lfu-cache(需要O(1),所以挺难的)的更多相关文章
- [LeetCode] LFU Cache 最近最不常用页面置换缓存器
Design and implement a data structure for Least Frequently Used (LFU) cache. It should support the f ...
- Leetcode: LFU Cache && Summary of various Sets: HashSet, TreeSet, LinkedHashSet
Design and implement a data structure for Least Frequently Used (LFU) cache. It should support the f ...
- LFU Cache
2018-11-06 20:06:04 LFU(Least Frequently Used)算法根据数据的历史访问频率来淘汰数据,其核心思想是“如果数据过去被访问多次,那么将来被访问的频率也更高”. ...
- LeetCode LFU Cache
原题链接在这里:https://leetcode.com/problems/lfu-cache/?tab=Description 题目: Design and implement a data str ...
- POJ 1275 Cashier Employment 挺难的差分约束题
http://poj.org/problem?id=1275 题目大意: 一商店二十四小时营业,但每个时间段需求的雇员数不同(已知,设为R[i]),现有n个人申请这份工作,其可以从固定时间t连续工作八 ...
- [LeetCode] 460. LFU Cache 最近最不常用页面置换缓存器
Design and implement a data structure for Least Frequently Used (LFU) cache. It should support the f ...
- leetcode 146. LRU Cache 、460. LFU Cache
LRU算法是首先淘汰最长时间未被使用的页面,而LFU是先淘汰一定时间内被访问次数最少的页面,如果存在使用频度相同的多个项目,则移除最近最少使用(Least Recently Used)的项目. LFU ...
- 72. Edit Distance(困难,确实挺难的,但很经典,双序列DP问题)
Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2 ...
- Leetcode:LRU Cache,LFU Cache
在Leetcode上遇到了两个有趣的题目,分别是利用LRU和LFU算法实现两个缓存.缓存支持和字典一样的get和put操作,且要求两个操作的时间复杂度均为O(1). 首先说一下如何在O(1)时间复杂度 ...
随机推荐
- Python之code对象与pyc文件(二)
上一节:Python之code对象与pyc文件(一) 创建pyc文件的具体过程 前面我们提到,Python在通过import或from xxx import xxx时会对module进行动态加载,如果 ...
- Python动态属性和特性(一)
在Python中,数据的属性和处理数据的方法统称为属性.其实,方式只是可调用的属性.除了这二者之外,我们还可以创建特性(property),在不改变类接口的前提下,使用存取方法(即读取值和设置值方法) ...
- docker容器utf-8编码问题
locale -a export LANG=C.UTF-8 locale 在docker容器中python脚本汉字的会乱码 按照上面的方法暂时的设置下容器 编码可以解决脚本中文乱码问题
- luogu2774 方格取数问题
最大点权独立集,参见胡伯涛论文 #include <iostream> #include <cstring> #include <cstdio> #include ...
- 第二章 jquery的dom操作
三个方面 dom核心,html-dom和css-dom 一. 1.dom core核心 document.getElementsByTagName("form") 获取表单 ...
- Leetcode 427.建立四叉树
建立四叉树 我们想要使用一棵四叉树来储存一个 N x N 的布尔值网络.网络中每一格的值只会是真或假.树的根结点代表整个网络.对于每个结点, 它将被分等成四个孩子结点直到这个区域内的值都是相同的. 每 ...
- DefaultTransactionStatus源码
package org.springframework.transaction.support; import org.springframework.transaction.NestedTransa ...
- Python Mysql学习总结
任何应用都离不开数据,所以在学习python的时候,当然也要学习一个如何用python操作数据库了.MySQLdb就是python对mysql数据库操作的模块.官方Introduction : MyS ...
- 【bzoj1604】[Usaco2008 Open]Cow Neighborhoods 奶牛的邻居 旋转坐标系+并查集+Treap/STL-set
题目描述 了解奶牛们的人都知道,奶牛喜欢成群结队.观察约翰的N(1≤N≤100000)只奶牛,你会发现她们已经结成了几个“群”.每只奶牛在吃草的时候有一个独一无二的位置坐标Xi,Yi(l≤Xi,Yi≤ ...
- BZOJ1068 [SCOI2007]压缩 【区间dp】
题目 给一个由小写字母组成的字符串,我们可以用一种简单的方法来压缩其中的重复信息.压缩后的字符串除了小 写字母外还可以(但不必)包含大写字母R与M,其中M标记重复串的开始,R重复从上一个M(如果当前位 ...