LeetCode_146 LRUCache (链表题)

题目地址:https://leetcode-cn.com/problems/lru-cache/

题目:

运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制。它应该支持以下操作: 获取数据 get 和 写入数据 put

获取数据 get(key) - 如果密钥 (key) 存在于缓存中,则获取密钥的值(总是正数),否则返回 -1。
写入数据 put(key, value) - 如果密钥不存在,则写入其数据值。当缓存容量达到上限时,它应该在写入新数据之前删除最近最少使用的数据值,从而为新的数据值留出空间。

进阶:

你是否可以在 O(1) 时间复杂度内完成这两种操作?

示例:

LRUCache cache = new LRUCache( 2 /* 缓存容量 */ );

cache.put(1, 1);
cache.put(2, 2);
cache.get(1);       // 返回  1
cache.put(3, 3);    // 该操作会使得密钥 2 作废
cache.get(2);       // 返回 -1 (未找到)
cache.put(4, 4);    // 该操作会使得密钥 1 作废
cache.get(1);       // 返回 -1 (未找到)
cache.get(3);       // 返回  3
cache.get(4);       // 返回  4

试题分析:

这道题考察的是链表的一个综合应用,LRU算法大家都知道,核心思想就是当LRUCache中命中的时候返回该值,并将该值移到LRU链表的头节点,如果没有命中返回异常值;在向LRUCache中put值时需要判断Cache中有没有该值,如果已经有了则返回该值并将该值放到链表头,如果没有该值则要判断链表有没有满,如果链表已满则删除链表尾的节点再将新节点插入链表头,如果链表未满则直接插入到链表头。

整个过程听起来不难,不过在实现过程中,光有一个LRU链表的话实现起来没法做到O(1),我们都知道在链表中查找值是O(n)的时间复杂度,无法做到O(1),这里就需要借助于一个HashMap,将链表中所有的cache节点都放在HashMap中,在每次对LRUCache进行操作的时候都需要先通过HashMap进行判断在cache中是否已经包含该值,HashMap的随机读时间复杂度是O(1)。具体代码逻辑可以直接看下面代码实现,逻辑就是上面提到的算法思路。

代码:

public class LRUCache_146 {
    private List<CacheNode> cacheList;
    private Map<Integer, CacheNode> cacheMap;
    private int capacity;

    public LRUCache_146(int capacity) {
        cacheList = new LinkedList<CacheNode>();
        cacheMap = new HashMap<Integer, CacheNode>(capacity);
        this.capacity = capacity;
    }

    public int get(int key) {
        if(cacheMap.containsKey(key)){
            cacheList.remove(cacheMap.get(key));
            cacheList.add(0, cacheMap.get(key));
            return cacheMap.get(key).value;
        }else{
            return -1;
        }
    }

    public void put(int key, int value) {
        if(cacheMap.containsKey(key)){
            cacheList.remove(cacheMap.get(key));
            cacheList.add(0, cacheMap.get(key));
        }else{
            //如果cache中没有该值则插入
            if(cacheMap.size()==capacity){
                //cache已满则需要先删除末尾节点再将新值插入队头
                cacheMap.remove(cacheList.get(cacheList.size()-1).key);
                cacheList.remove(cacheList.size()-1);
                CacheNode node = new CacheNode(key,value);
                cacheMap.put(key, node);
                cacheList.add(0, node);
            }else{
                CacheNode node = new CacheNode(key,value);
                cacheMap.put(key, node);
                cacheList.add(0, node);
            }
        }
    }

    private class CacheNode{
        int key;
        int value;
        public CacheNode(int key, int value){
            this.key = key;
            this.value = value;
        }
    }
}

源码路径:com.monkey01.linkedlist.LRUCache_146

配套测试代码路径:test目录com.monkey01.linkedlist.LRUCache_146Test

https://github.com/feiweiwei/LeetCode4Java.git

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容

  • Java继承关系初始化顺序 父类的静态变量-->父类的静态代码块-->子类的静态变量-->子类的静态代码快-->父...
    第六象限阅读 2,132评论 0 9
  • 分析常用集合的底层的原理:ArrayList、Vector、LinckedList、HashMap、HashSet...
    仕明同学阅读 2,177评论 1 13
  • 面试必背 会舍弃、总结概括——根据我这些年面试和看面试题搜集过来的知识点汇总而来 建议根据我的写的面试应对思路中的...
    luoyangzk阅读 6,703评论 6 173
  • 什么是Map 不同于List单列的线性结构,Map提供的是一种双列映射的存储集合,它能够提供一对一的数据处理...
    still_loving阅读 3,235评论 0 30
  • 更换了所有的社交图片,个性签名,个性留言。 等待着焕然一新的心境; 能够重燃欢乐生活的信念。 一丝一丝的剥离; 无...
    雪韵_莲心阅读 485评论 2 4