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)时间复杂度 ...
随机推荐
- [转] vuex最简单、最直白、最全的入门文档
前言 我们经常用element-ui做后台管理系统,经常会遇到父组件给子组件传递数据,下面一个简单的例子,点击按钮,把弹框显示变量数据通过子组件的props属性传递,子组件通过$emit事件监听把数据 ...
- python学习-- Django传递数据给JS
var List = {{ List|safe }};//safe 必须存在
- 让读者快速了解RocketMQ消息中间件需要解决哪些问题
本文首先引出消息中间件通常需要解决哪些问题,在解决这些问题当中会遇到什么困难,Apache RocketMQ作为阿里开源的一款高性能.高吞吐量的分布式消息中间件否可以解决,规范中如何定义这些问题.然后 ...
- 设计模式(八)组合模式 Composite
组合模式: 允许你将对象组合成树形结构来表现“整体/部分”层次结构.组合能让客户以一致的方式处理个别对象以及对象组合. 组合模式适用于创建复杂的对象,这个对象包含某些个别的对象以及这些对象的组合. 从 ...
- 【Luogu】P1472奶牛家谱(DP)
题目链接 这是一道考思维的好题. 一开始设f[i][j]是i个点刚好j层的方案数,死活调不出来,看题解发现可以改为<=j层的方案数,最后输出f[n][m]-f[n][m-1]就好了. 对于计算考 ...
- 解决ul的li横向排列换行的问题
1. 问题现象 先看下面的html结构: <div> <ul> <li><img src='./img/1.jpg'></li> <l ...
- localStorage的用法
1.在HTML5中,本地存储是一个window的属性,包括localStorage和sessionStorage,前者是一直存在本地的,后者是伴随着session,窗口一旦关闭就消失了.二者用法完全相 ...
- POJ #1025 Department
模拟题. 这题第一个障碍是现在少见的循环电梯 ('pater-noster' elevator) "The building has `pater-noster' elevator, i.e ...
- BZOJ3991 [SDOI2015]寻宝游戏 【dfs序 + lca + STL】
题目 小B最近正在玩一个寻宝游戏,这个游戏的地图中有N个村庄和N-1条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩家可以任意选择一个村庄,瞬间转移到这个村庄,然后可以任意在地图的道路 ...
- Codeforces - Avito Code Challenge 2018
Portal A. Antipalindrome 暴力. B. Businessmen Problems 暴力. C. Useful Decomposition 居然不是C打头的?! 将一棵树划分成若 ...