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 1407 树形背包 Caves

    这道题可以和POJ 2486 树形背包DP Apple Tree比较着来做. 参考题解 #include <iostream> #include <cstdio> #inclu ...

  2. MAC OS X 终端命令入门

    在这里记下..防止丢失 pwd 当前工作目录 cd(不加参数) 进root cd(folder) 进入文件夹 cd .. 上级目录 cd ~ 返回root cd - 返回上一个访问的目录 rm 文件名 ...

  3. python踩坑系列——报错后修改了.py文件,但是依然报错

    一开始.py文件中的函数名大小写错了,但是在终端是对的,报错: 'module' object has no attribute '某函数名' 后来就去修改.py文件.结果重新import该.py文件 ...

  4. Welcome-to-Swift-23访问控制(Access Control)

    访问控制可以限定你在源文件或模块中访问代码的级别,也就是说可以控制哪些代码你可以访问,哪些代码你不能访问.这个特性可以让我们隐藏功能实现的一些细节,并且可以明确的指定我们提供给其他人的接口中哪些部分是 ...

  5. 二进制<2>

    位运算简介及实用技巧(二):进阶篇(1) =====   真正强的东西来了!   ===== 二进制中的1有奇数个还是偶数个    我们可以用下面的代码来计算一个32位整数的二进制中1的个数的奇偶性, ...

  6. 模拟tap事件和longTap事件

    移动端模拟tap和longTap事件,基本原理就是在touchstart和touchend事件中,计算触摸的位移和时间差,位移在一定范围内(轻微滑动),时间小于150ms为tap事件,时间大于300m ...

  7. js对象的扁平化与反扁平化

    Object.flatten = function(obj){ var result = {}; function recurse(src, prop) { var toString = Object ...

  8. Java2WSDL 和 WSDL2Java(Axis)

    原文地址:https://www.ibm.com/developerworks/cn/webservices/ws-axisfaq/ 生成或取得WSDL文件 生成客户端或服务端代码 执行WSDL2Ja ...

  9. [暑假集训--数位dp]LightOj1205 Palindromic Numbers

    A palindromic number or numeral palindrome is a 'symmetrical' number like 16461 that remains the sam ...

  10. Java 学习(2):java 基础概念

    Java作为一种面向对象语言.支持以下基本概念: 多态 继承 封装 抽象 类 对象 实例 方法 重载 基础语法: 一个Java程序可以认为是一系列对象的集合,而这些对象通过调用彼此的方法来协同工作.以 ...