LeetCode解题报告:LRU Cache
Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and set.
get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.set(key, value) - Set or insert the value if the key is not already present. When the cache reached its capacity, it should invalidate the least recently used item before inserting a new item.
思路:Java的LinkedHashMap可以实现最近最少使用(LRU)的次序。类似于HashMap。详见《JAVA编程思想(第4版)》P487.
题目要求是一个固定大小的cache,因此需要一个变量maxCapacity来记录容量大小,用LinkedHashMap存储数据。在添加数据set()方法时,判断一下是否达到maxCapacity,如果cache已经满了,remove掉最长时间不使用的数据,然后put进新的数据。
注意:HashMap,LinkedHashMap,TreeMap的区别,详细看看StackOverFlow
LinkedHashMap最常用的是LRU cache的实现。
如果用C++实现的话, hashmap + 双向链表:用 双向链表记录value 用hashmap记录 key值在链表中的位置(指针)。
unordered_map<int, list<CacheNode>:: iterator> cacheMap;
题解:
import java.util.LinkedHashMap;
public class LRUCache {
LinkedHashMap<Integer, Integer> linkedmap;
int maxCapacity;
public LRUCache(int capacity) {
this.maxCapacity = capacity;
this.linkedmap = new LinkedHashMap<Integer, Integer>(capacity, 1f, true);
}
public int get(int key) {
if (linkedmap.containsKey(key))
return linkedmap.get(key);
else
return -1;
}
public void set(int key, int value) {
int size = linkedmap.size();
if ((size < maxCapacity) || (linkedmap.containsKey(key))) {
linkedmap.put(key, value);
} else if (size >= maxCapacity) {
Iterator<Integer> it = linkedmap.keySet().iterator();//iterator method is superior the toArray(T[] a) method.
linkedmap.remove(it.next());
linkedmap.put(key, value);
}
}
}
结题遇到的问题:
1.下面这段代码提交的时候超时了。
import java.util.LinkedHashMap;
public class LRUCache {
LinkedHashMap<Integer, Integer> linkedmap;
int maxCapacity;
public LRUCache(int capacity) {
this.maxCapacity = capacity;
this.linkedmap = new LinkedHashMap<Integer, Integer>(capacity, 1f, true);
}
public int get(int key) {
if (linkedmap.containsKey(key))
return linkedmap.get(key);
else
return -1;
}
public void set(int key, int value) {
int size = linkedmap.size();
if ((size < maxCapacity) || (linkedmap.containsKey(key))) {
linkedmap.put(key, value);
} else if (size >= maxCapacity) {
Integer[] keyArray = linkedmap.keySet().toArray(new Integer[0]);//这是超时的代码,采用Iterator不会超时。
linkedmap.remove(keyArray[0]);
linkedmap.put(key, value);
}
}
}
2.Roger自己实现LinkedHashMap的功能,采用双向链表和哈希表。效率略低于LinkedHashMap.(644ms>548ms)
import java.util.HashMap;
public class LRUCache {
private HashMap<Integer, Entry<Integer>> index;
private UDFList<Integer> data;
public LRUCache(int capacity) {
index = new HashMap<Integer, Entry<Integer>>(capacity);
data = new UDFList<Integer>(capacity);
}
public int get(int key) {
if (!isExist(key)) {
index.remove(key);
return -1;
}
if (!index.get(key).equals(data.head)) {
Entry<Integer> nodePtr = data.adjust(index.get(key));
index.put(key, nodePtr);
}
return index.get(key).element;
}
public void set(int key, int value) {
if (isExist(key)) {
data.remove(index.get(key));
}
index.put(key, data.push(value));
}
private boolean isExist(int key) {
if (index.get(key) == null) {
return false;
}
if (index.get(key).element == null) {
return false;
}
return true;
}
public class UDFList<E> {
public Entry<E> head;
public Entry<E> tail;
public final int size;
public int length = 0;
public UDFList(int size) {
head = new Entry<E>(null, null, null);
tail = head;
this.size = size;
}
public Entry<E> adjust(Entry<E> node) {
if (node.equals(tail)) {
tail = tail.previous;
tail.next = null;
node.previous = null;
} else if (node.equals(head)) {
node = null;
return head;
} else {
node.previous.next = node.next;
node.next.previous = node.previous;
}
head.previous = node;
node.next = head;
head = node;
node = null;
return head;
}
public Entry<E> push(E e) {
Entry<E> newNode = new Entry<E>(e, null, null);
if (length == 0) {
head = newNode;
tail = head;
} else {
head.previous = newNode;
newNode.next = head;
head = newNode;
}
if (length == size) {
remove(tail);
}
length++;
return head;
}
public void remove(Entry<E> node) {
if (node == null)
return;
node.element = null;
if (node.equals(head)) {
head = head.next;
} else if (node.equals(tail)) {
tail = tail.previous;
tail.next = null;
} else {
node.previous.next = node.next;
node.next.previous = node.previous;
}
node = null;
length--;
}
}
public class Entry<E> {
public E element;
public Entry<E> previous;
public Entry<E> next;
public Entry(E element, Entry<E> next, Entry<E> previous) {
this.element = element;
this.next = next;
this.previous = previous;
}
}
}
LeetCode解题报告:LRU Cache的更多相关文章
- LeetCode解题报告:Linked List Cycle && Linked List Cycle II
LeetCode解题报告:Linked List Cycle && Linked List Cycle II 1题目 Linked List Cycle Given a linked ...
- leetcode解题报告(2):Remove Duplicates from Sorted ArrayII
描述 Follow up for "Remove Duplicates": What if duplicates are allowed at most twice? For ex ...
- LeetCode题解: LRU Cache 缓存设计
LeetCode题解: LRU Cache 缓存设计 2014年12月10日 08:54:16 邴越 阅读数 1101更多 分类专栏: LeetCode 版权声明:本文为博主原创文章,遵循CC 4 ...
- 【LeetCode】146. LRU Cache 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 字典+双向链表 日期 题目地址:https://le ...
- LRU算法&&LeetCode解题报告
题目 Design and implement a data structure for Least Recently Used (LRU) cache. It should support the ...
- LeetCode 解题报告索引
最近在准备找工作的算法题,刷刷LeetCode,以下是我的解题报告索引,每一题几乎都有详细的说明,供各位码农参考.根据我自己做的进度持续更新中...... ...
- 【LeetCode OJ】LRU Cache
Problem Link: http://oj.leetcode.com/problems/lru-cache/ Long long ago, I had a post for implementin ...
- 【LeetCode】146. LRU Cache
LRU Cache Design and implement a data structure for Least Recently Used (LRU) cache. It should suppo ...
- LeetCode OJ:LRU Cache(最近使用缓存)
Design and implement a data structure for Least Recently Used (LRU) cache. It should support the fol ...
随机推荐
- linux bash下 快捷键
c + a # 光标跳转到最左 c + e # 光标跳转到最后 c + w # 删除最后输入的单词 c + u # 删除整行 c + k # 删除光标到末尾 c + l # 清屏 c + z # 挂起 ...
- Oracle中not exists 与not in 的使用情况
1.在oracle11g以上版本,oracle已经做了优化,能够自动将in优化成exists方式,因此oracle11g以上版本,使用in和exists效果是一样的. 2.在oracle中,使用not ...
- .NET设计模式(10):装饰模式(Decorator Pattern)
.NET设计模式(10):装饰模式(Decorator Pattern) 装饰模式(Decorator Pattern) --.NET设计模式系列之十 年月..在....对于..由于使用装饰模 ...
- C#当中的多线程_任务并行库(中)
发现自己有点懒了!也可能是越往后越难了,看书理解起来有点费劲,所以这两天就每天更新一点学习笔记吧. 4.5 将APM模式转化为任务 书上提供的三种方式 方式一: class Program ...
- mvc5 + ef6 + autofac搭建项目(四)
在列表页面,点击新增,弹出窗口实现视屏上传,这里存在一个问题,就是大文件上传的问题,iis出于安全问题,有限制,当然这不是大问题,解决也很容易: 见截图: 请忽略视屏文件,看得懂的请装作不懂. 源码 ...
- python小爬虫【1】
爬取百度贴吧的图片 分析贴吧源代码,图片所在位置是:<img class="BDE_Image" src=“........jpg” pic_ext..... 所以正则匹配是 ...
- Win7系统中MS SQLServer 2005 无法连接
今天重装了一下Win7系统,数据库自然也重新装了一下.谁知道竟然无法连接,使用通用的解决问题方法一一测试: 1.启动数据库主要服务(因为我安装时取消了自动启动),也无法连接: 2.查看,windows ...
- 邓白氏编码(duns number)申请入口的路径-苹果开发者申请必
http://tieba.baidu.com/p/3861287522 这个网址有详细的介绍
- cocos2dx系列笔记(1)- windows环境配置前篇
cocos2dx升级之旅,请多指教~ 本篇是本人搭建cocos2dx-Windows 64位环境的配置说明,仅供参考. 开发准备 搭建环境肯定需要准备好所有工具,只有把工具都准备好了,才能撸起袖子干活 ...
- 配置hive元数据库mysql时候出现 Unable to find the JDBC database jar on host : master
解决办法: cd /usr/share/java/,(没有java文件夹,自行创建)rz mysql-connector-java-***.jar,mv mysql-connector-java-* ...