[LeetCode]460. LFU Cache
来源:互联网 发布:阿里云备案承诺书demo 编辑:程序博客网 时间:2024/06/06 01:12
https://leetcode.com/problems/lfu-cache/#/description
实现一个 Least Frequently Used (LFU),保存访问频率最高的capacity个数,如果要淘汰的可能有多个数频率相同,则淘汰最后一次访问时间最靠前的
lintcode本题测试集不完整
用bucket链表,每个bucket内保存同一个count的所有元素,bucket内部用类似LRU来实现保存元素(head && tail),这样保证在O(1)时间内插入、删除特定元素或者进行淘汰
public class LFUCache { int capacity; DListBucket head; DListBucket tail; HashMap<Integer, Node> map; HashMap<Integer, DListBucket> bucketMap; class DListBucket { int count; Node nodeHead; Node nodeTail; DListBucket pre; DListBucket next; public DListBucket(int count) { this.count = count; nodeHead = new Node(0, 0, 0); nodeTail = new Node(0, 0, 0); nodeHead.next = nodeTail; nodeTail.pre = nodeHead; } } class Node { int key; int val; int count; Node pre; Node next; public Node(int key, int val, int count) { this.key = key; this.val = val; this.count = count; } } // @param capacity, an integer public LFUCache(int capacity) { // Write your code here this.capacity = capacity; head = new DListBucket(Integer.MIN_VALUE); tail = new DListBucket(Integer.MIN_VALUE); head.next = tail; tail.pre = head; map = new HashMap(); bucketMap = new HashMap(); } // @param key, an integer // @param value, an integer // @return nothing public void put(int key, int value) { // Write your code here if (capacity == 0) { return; } if (map.containsKey(key)) { Node node = map.get(key); node.pre.next = node.next; node.next.pre = node.pre; DListBucket next = null; if (bucketMap.get(node.count).next.count != node.count + 1) { next = insertBucket(node.count + 1, bucketMap.get(node.count)); } else { next = bucketMap.get(node.count).next; } node.count++; node.val = value; node.pre = next.nodeTail.pre; node.next = next.nodeTail; next.nodeTail.pre = node; node.pre.next = node; } else { Node node = new Node(key, value, 1); map.put(key, node); DListBucket next = null; if (head.next.count != 1) { next = insertBucket(1, head); } else { next = head.next; } node.pre = next.nodeTail.pre; node.next = next.nodeTail; next.nodeTail.pre = node; node.pre.next = node; if (map.size() > capacity) { removeLastNode(node); } } } private void removeLastNode(Node cur) { Node nodeHead = head.next.nodeHead; Node node = null; if (nodeHead.next == cur && head.next.next.nodeHead.next != head.next.next.nodeTail) { node = head.next.next.nodeHead.next; } else { node = head.next.nodeHead.next; } node.pre.next = node.next; node.next.pre = node.pre; map.remove(node.key); } public int get(int key) { // Write your code here if (!map.containsKey(key)) { return -1; } Node node = map.get(key); node.pre.next = node.next; node.next.pre = node.pre; DListBucket next = null; if (bucketMap.get(node.count).next.count != node.count + 1) { next = insertBucket(node.count + 1, bucketMap.get(node.count)); } else { next = bucketMap.get(node.count).next; } node.count++; node.pre = next.nodeTail.pre; node.next = next.nodeTail; next.nodeTail.pre = node; node.pre.next = node; return node.val; } private DListBucket insertBucket(int count, DListBucket pre) { DListBucket bucket = new DListBucket(count); bucket.next = pre.next; bucket.pre = pre; pre.next = bucket; bucket.next.pre = bucket; bucketMap.put(count, bucket); return bucket; }}
0 0
- LeetCode 460. LFU Cache
- LeetCode 460. LFU Cache
- [LeetCode]460. LFU Cache
- Leetcode 460. LFU Cache
- Leetcode 460. LFU Cache
- leetcode 460. LFU Cache
- LeetCode 460. LFU Cache
- leetcode 146. LRU Cache 460. LFU Cache
- [Leetcode] 460. LFU Cache 解题报告
- [LeetCode] LFU Cache
- 460. LFU Cache
- 460. LFU Cache
- 460. LFU Cache
- 20170604-leetcode-460-LFU Cache
- LFU Cache
- LFU Cache
- 460. LFU Cache O(1)算法 C++
- [Leetcode-460]LFU Cache 最近不常用页面交换
- 第二章
- 文章标题
- 二叉树的最大深度
- 二分的终止条件具体怎么搞?
- 详解SpringMVC中Controller的方法中参数的工作原理[附带源码分析]
- [LeetCode]460. LFU Cache
- 经典查找算法
- 威佐夫博弈(高精度)
- 可重入与不可重入函数的区别以及对程序的影响
- Android 之dialog 以及界面设计规则,画板项目需求分析,变换画线Path 大小 长度Canvase变换
- Caffe源码解读(一):代码组织结构
- Unix环境高级编程读书笔记(2.1)
- XMLHttpRequest对象的常用属性
- HM学习一