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),所以挺难的)的更多相关文章

  1. [LeetCode] LFU Cache 最近最不常用页面置换缓存器

    Design and implement a data structure for Least Frequently Used (LFU) cache. It should support the f ...

  2. 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 ...

  3. LFU Cache

    2018-11-06 20:06:04 LFU(Least Frequently Used)算法根据数据的历史访问频率来淘汰数据,其核心思想是“如果数据过去被访问多次,那么将来被访问的频率也更高”. ...

  4. LeetCode LFU Cache

    原题链接在这里:https://leetcode.com/problems/lfu-cache/?tab=Description 题目: Design and implement a data str ...

  5. POJ 1275 Cashier Employment 挺难的差分约束题

    http://poj.org/problem?id=1275 题目大意: 一商店二十四小时营业,但每个时间段需求的雇员数不同(已知,设为R[i]),现有n个人申请这份工作,其可以从固定时间t连续工作八 ...

  6. [LeetCode] 460. LFU Cache 最近最不常用页面置换缓存器

    Design and implement a data structure for Least Frequently Used (LFU) cache. It should support the f ...

  7. leetcode 146. LRU Cache 、460. LFU Cache

    LRU算法是首先淘汰最长时间未被使用的页面,而LFU是先淘汰一定时间内被访问次数最少的页面,如果存在使用频度相同的多个项目,则移除最近最少使用(Least Recently Used)的项目. LFU ...

  8. 72. Edit Distance(困难,确实挺难的,但很经典,双序列DP问题)

    Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2 ...

  9. Leetcode:LRU Cache,LFU Cache

    在Leetcode上遇到了两个有趣的题目,分别是利用LRU和LFU算法实现两个缓存.缓存支持和字典一样的get和put操作,且要求两个操作的时间复杂度均为O(1). 首先说一下如何在O(1)时间复杂度 ...

随机推荐

  1. UVa 1629 DP Cake slicing

    题意: 一块n×m的蛋糕上有若干个樱桃,要求切割若干次以后,每块蛋糕上有且仅有1个樱桃.求最小的切割长度. 分析: d(u, d, l, r)表示切割矩形(u, d, l, r)所需要的最小切割长度. ...

  2. POJ - 1321 深度优先搜索入门

    #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> us ...

  3. JAVA-基础(四) Aarryas 数组

    1. asList( )方法 返回一个被指定数组支持的List.换句话说,列表和数组访问的是同一个 单元.它具有如下的形式: static List asList(Object[ ] array) 2 ...

  4. 1px的实现

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  5. Android之高效率截图

    本文来自网易云社区 作者:孙圣翔 在一张Android手机上截图有好多办法,为了能够高效率的截图,我几乎把所有的方法都尝试了一般.走了好多路,也遇到了好多的问题. 只是想记录下这其中的不容易. 下面所 ...

  6. 【LeetCode】Binary Tree Preorder Traversal(二叉树的前序遍历)

    这道题是LeetCode里的第144道题. 题目要求: 给定一个二叉树,返回它的 前序 遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [1,2,3] 进阶: 递归算法很 ...

  7. uiautomator 一个简单脚本创建流程

    http://www.codeceo.com/article/android-ui-auto-test.html

  8. BZOJ3992 [SDOI2015]序列统计 【生成函数 + 多项式快速幂】

    题目 小C有一个集合S,里面的元素都是小于M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数 列,数列中的每个数都属于集合S.小C用这个生成器生成了许多这样的数列.但是小C有一个问题 ...

  9. 换教室(bzoj 4720)

    Description 对于刚上大学的牛牛来说,他面临的第一个问题是如何根据实际情况申请合适的课程.在可以选择的课程中,有2n节 课程安排在n个时间段上.在第i(1≤i≤n)个时间段上,两节内容相同的 ...

  10. 转 Python——UnicodeEncodeError: 'ascii' codec can't encode/decode characters

    转自: http://blog.csdn.net/zuyi532/article/details/8851316 我是写爬虫的时候遇到的问题,百度了一下,先贴解决方案: 在代码中加入: import ...