原题链接在这里:https://leetcode.com/problems/lru-cache/

题目:

Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and put.

get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.
put(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.

Follow up:
Could you do both operations in O(1) time complexity?

Example:

LRUCache cache = new LRUCache( 2 /* capacity */ );cache.put(1, 1);
cache.put(2, 2);
cache.get(1);       // returns 1
cache.put(3, 3);    // evicts key 2
cache.get(2);       // returns -1 (not found)
cache.put(4, 4);    // evicts key 1
cache.get(1);       // returns -1 (not found)
cache.get(3);       // returns 3
cache.get(4);       // returns 4

题解:

可以通过HashMap 和 Double LinkedList来完成。每个key, value用一个Node 来储存,按照添加顺序一个一个放在list 的head后面。同时把<key, node>放在HashMap中。

get时看HashMap中是否有这个key, 有的话就找到对应的node, 在node里取出对应的value. 同时更新该node 在list中的位置。

set时分三种情况:1. 看HashMap中是否有这个key, 有的话说明本来就有这个key对应的node, 只需要把原有node的value更改并且更新该node 在list中位置即可。

2. HashMap中没有这个key, 同时HashMap的size未达到capacity, 那么新建一个node, 加入HashMap 和 list中即可。

3. HashMap中没有这个key, 同时HashMap的size已经等于capacity, 多加就要溢出,所以按照2中完成添加后要从HashMap 和 list中都去掉最老的node.

Time Complexity: get, O(1). put O(1).

Space: O(n).

AC Java:

 1 class Node{
 2     Node prev;
 3     Node next;
 4     int key;
 5     int value;
 6     Node(int key, int value){
 7         this.key = key;
 8         this.value = value;
 9     }
10 }
11
12 public class LRUCache {
13     Node head;
14     Node tail;
15     int capacity;
16     HashMap<Integer, Node> hm;
17
18     public LRUCache(int capacity) {
19         head = new Node(-1,-1);
20         tail = new Node(1,1);
21         head.next = tail;
22         tail.prev = head;
23         this.capacity = capacity;
24         hm = new HashMap<Integer, Node>();
25     }
26
27     public int get(int key) {
28         if(hm.containsKey(key)){
29             Node p = hm.get(key); //error
30             putToHead(p);   //put p to the newest position of list
31             return p.value;
32         }
33         return -1;
34     }
35
36     public void set(int key, int value) {
37         if(hm.containsKey(key)){
38             Node p = hm.get(key);
39             p.value = value;
40             putToHead(p);   //update p's position in the list
41         }else if(hm.size() < capacity){
42             Node p = new Node(key, value);
43             hm.put(key,p);
44             putToHead(p);
45         }else{
46             Node p = new Node(key,value);
47             hm.put(key,p);
48             putToHead(p);
49             int oldKey = removeOldest();    //remove oldest node from the list
50             hm.remove(oldKey);  //remove oldest node from hashmap
51         }
52     }
53
54     private void putToHead(Node p){
55         if(p.prev != null && p.next != null){
56             p.prev.next = p.next;
57             p.next.prev = p.prev;
58         }
59         p.prev = head;
60         p.next = head.next;
61         head.next.prev = p;
62         head.next = p;
63     }
64
65     private int removeOldest(){
66         Node oldest = tail.prev;
67         int oldKey = oldest.key;
68         oldest.prev.next = tail;
69         tail.prev = oldest.prev;
70         return oldKey;
71     }
72 }

另一种方法是用LinkedHashMap, 这种数据结构本身已经把HashMap按照添加顺序放好了。

可以参见这个网页:http://www.tutorialspoint.com/java/java_linkedhashmap_class.htm

所以实现起来很简洁,get时需要更新位置,更新位置是通过删掉旧的,复制一下加回去。

set时参照上面的三种情况即可。

AC Java:

 1 import java.util.LinkedHashMap;
 2 public class LRUCache {
 3     LinkedHashMap<Integer, Integer> linkedHM;
 4     int capacity;
 5     public LRUCache(int capacity) {
 6         linkedHM = new LinkedHashMap<Integer, Integer>();
 7         this.capacity = capacity;
 8     }
 9
10     public int get(int key) {
11         if(linkedHM.containsKey(key)){
12             int val = linkedHM.get(key);
13             linkedHM.remove(key);
14             linkedHM.put(key,val);
15             return val;
16         }
17         return -1;
18     }
19
20     public void set(int key, int value) {
21         if(linkedHM.containsKey(key)){
22             linkedHM.remove(key);
23             linkedHM.put(key,value);
24         }else if(linkedHM.size() < capacity){
25             linkedHM.put(key,value);
26         }else{
27             int oldKey = linkedHM.keySet().iterator().next();
28             linkedHM.remove(oldKey);
29             linkedHM.put(key,value);
30         }
31     }
32 }

转载于:https://www.cnblogs.com/Dylan-Java-NYC/p/4935048.html

LeetCode LRU Cache相关推荐

  1. [LeetCode]LRU Cache有个问题,求大神解答【已解决】

    题目: Design and implement a data structure for Least Recently Used (LRU) cache. It should support the ...

  2. LeetCode LRU Cache(最近最少使用缓存)

    问题:设计一个最近最少使用缓存.支持get和put操作 1.如果get(key)中,key在缓存中不存在,返回-1 2.put(key,value),如果key在缓存中不存在,则插入.当缓存到达容量时 ...

  3. Leetcode: LRU Cache

    题目 Design and implement a data structure for Least Recently Used (LRU) cache. It should support the ...

  4. [leetcode]LRU Cache

    双链表+map 实现.所有数据存在链表里,map里存key到Node*的映射.注意当删除时除了要从链表尾部删除节点外,还要map.erase(it).Node里也要有key,因为为了删除时方便找到it ...

  5. 【LeetCode】LRU Cache 解决报告

    插话:只写了几个连续的博客,博客排名不再是实际"远在千里之外"该.我们已经进入2一万内. 再接再厉.油! Design and implement a data structure ...

  6. 【重点】LeetCode 146. LRU Cache

    LeetCode 146. LRU Cache 1.Solution1 本博客转载自:http://www.cnblogs.com/grandyang/p/4587511.html 这道题让我们实现一 ...

  7. 代码写对了还挂了?程序媛小姐姐从 LRU Cache 带你看面试的本质

    来源 | 码农田小齐 责编 |  Carol 前言 在讲这道题之前,我想先聊聊「技术面试究竟是在考什么」这个问题. 技术面试究竟在考什么 在人人都知道刷题的今天,面试官也都知道大家会刷题准备面试,代码 ...

  8. 从 LRU Cache 带你看面试的本质

    前言 在讲这道题之前,我想先聊聊「技术面试究竟是在考什么」这个问题. 技术面试究竟在考什么 在人人都知道刷题的今天,面试官也都知道大家会刷题准备面试,代码大家都会写,那面试为什么还在考这些题?那为什么 ...

  9. linux cache lru回收,LRU cache 算法

    上周末同学问了一些操作系统的问题,涉及到LRU cache,顺便复习了一下. LRU是least recently used的缩写,意思是最近最少使用,是一种内存页面置换算法.根据程序设计局部性的原则 ...

最新文章

  1. 极客新闻——02、最高效的人都是最会休息的人
  2. android 6.0 log,android 6.0 logcat机制(二)logcat从logd中获取log保存到文件中
  3. nodejs启动机制分析
  4. 开源]OSharpNS 步步为营系列 - 1. 业务模块设计
  5. Easyui中使用jquery或js动态添加元素时出现的样式失效的解决方法
  6. ajax中get请求获取数据
  7. ERP项目实施记录05
  8. 大气辐射示意简单图_地理笔记 | N21 自然地理——大气的组成与垂直分层
  9. gis坐标北京54转WGS84坐标系
  10. OAuth2通过token访问资源服务器
  11. 手把手教你玩maven脚手架
  12. java 汇率换算_汇率转换示例代码
  13. 《读者》的“卷首语” (五)
  14. mysql参数之max_connect_errors
  15. C语言 课程设计 实现简单的车辆管理系统
  16. 新版白话空间统计(25):方向分布(标准差椭圆)
  17. 2012总结之pcode.Class
  18. 用户登录和用户注册案例
  19. 熬了三个大夜利用Python开发一个炸金花小游戏,注意别玩上瘾了~~(附完整源码)
  20. 信创蓝海 合作共赢:统信UOS代理商推介会(郑州站)成功举行

热门文章

  1. 面试题 04.01. 节点间通路
  2. 使用tensorflow object detection API 训练自己的目标检测模型 (三)
  3. python编写系统遇到的问题_python编写时遇到的小问题
  4. 安装Python psutil包
  5. oracle如何查看某个时间段调用的函数的异常信息_每天14点遭遇惊魂时刻,如何一步一步揪出真凶?...
  6. python oracle orm_Python - ORM(数据库相关)
  7. APP自动化测试系列之Appium介绍及运行原理
  8. homebrew安装
  9. Bella团队正在进行Flex Saving v2上线最后的准备工作
  10. 以太坊2.0合约余额新增2.62万ETH