leetcode 146.LRU缓存

思路一:哈希表模拟

如果只用哈希表进行模拟的话,需要开辟两个哈希表进行存储,一个装入数据,一个是记录数据key放入的次数。

然后,可以结合操作系统中最近最久算法的那个实例操作进行模拟,但是时间复杂度会O(n),因此并不是这道题的最优解,并且会因为时间限制通过不了,可以通过这个模拟方法复习操作系统,并且提升代码能力。

复制代码
class LRUCache {
    int volumn;
    Map<Integer,Integer>map;
    Map<Integer,Integer>count;
    int cnt=0;
    public LRUCache(int capacity) {
        this.volumn=capacity;
        map=new HashMap<>();
        count=new HashMap<>();
    }

    public int get(int key) {
        if(map.containsKey(key)){
            Set set=count.keySet();
            Iterator it=set.iterator();
            while(it.hasNext()){
                Integer tmp=(Integer)it.next();
                count.put(tmp,count.get(tmp)+1);
            }
            count.put(key,1);
            return map.get(key);
        }
        else
            return -1;
    }

    public void put(int key, int value) {
        if(!map.containsKey(key)){
            cnt++;
        }
        if(cnt>volumn&&!map.containsKey(key)){
            cnt--;
            Set set=count.keySet();
            Iterator it=set.iterator();
            int maxs=0;
            while(it.hasNext()){
                Integer tmp=(Integer)it.next();
                maxs=Math.max(maxs,count.get(tmp));
            }

            Set set1=count.keySet();
            Iterator its=set1.iterator();
            while(its.hasNext()){
                Integer tmp=(Integer)its.next();
                if(count.get(tmp)==maxs){
                    map.remove(tmp);
                    count.remove(tmp);
                    break;
                }
            }
            Set sets=count.keySet();
            Iterator itw=sets.iterator();
            while(itw.hasNext()){
                Integer tmp=(Integer)itw.next();
                count.put(tmp,count.get(tmp)+1);
            }
            map.put(key,value);
            count.put(key,1);
        }
        else{
            Set set1=count.keySet();
            Iterator it=set1.iterator();
            while(it.hasNext()){
                Integer tmp=(Integer)it.next();
                count.put(tmp,count.get(tmp)+1);
            }
            count.put(key,1);
            map.put(key,value);
        }
    }
}

/**
 * Your LRUCache object will be instantiated and called as such:
 * LRUCache obj = new LRUCache(capacity);
 * int param_1 = obj.get(key);
 * obj.put(key,value);
 */

思路二:用双向链表,哈希表作为辅助。

这个过程有点像自己在一堆书里拿书,就是灵神的那个题解思想,这里直接上代码。

注意事项:在写remove函数的时候,可能会出现空指针的异常,这是因为传入的参数可能是一个null,所以为了避免这种事情发生,我们要么就在函数前面加上声明特判null,要么就需要保证传入的结点必须是非null的,这样的话就需要对其他相关的函数进行约束。

复制代码
class LRUCache {
    private final int capacity;
    private class Node{
        Node pre;
        Node next;
        int key,value;
        public Node(int key,int value){
            this.key=key;
            this.value=value;
        }
    }
    private final Node dummy=new Node(0,0);
    private Map<Integer,Node>map=new HashMap<>();
    public LRUCache(int capacity) {
        this.capacity=capacity;
        dummy.next=dummy;
        dummy.pre=dummy;
    }
    
    public int get(int key) {
        Node t=getNode(key);
        return t!=null?t.value:-1;
    }
    
    public void put(int key, int value) {
        Node node=getNode(key);
        if(node!=null){
            node.value=value;
            return;
        }
        node=new Node(key,value);
        map.put(key,node);
        pullFront(node);
        if(map.size()>capacity){
            Node tmp=dummy.pre;
            remove(tmp);
            map.remove(tmp.key);
        }
    }
    public Node getNode(int key){
        if(!map.containsKey(key)){
            return null;
        }
        Node tmp=map.get(key);
        remove(tmp);
        pullFront(tmp);
        return tmp;
    }
    public void remove(Node tmp){
        tmp.pre.next=tmp.next;
        tmp.next.pre=tmp.pre;
    }
    public void pullFront(Node tmp){
        tmp.pre=dummy;
        tmp.next=dummy.next;
        tmp.pre.next=tmp;
        tmp.next.pre=tmp;
    }
}

/**
 * Your LRUCache object will be instantiated and called as such:
 * LRUCache obj = new LRUCache(capacity);
 * int param_1 = obj.get(key);
 * obj.put(key,value);
 */
相关推荐
苏渡苇1 分钟前
Redis 版本演进、新特性与协议那些事儿
数据库·redis·缓存·开源协议·redis版本·redis新特性
鬼蛟6 分钟前
Nacos
数据库·redis·缓存
码农阿豪24 分钟前
一次 AI 调用 15 万 Token 只花了 $0.058?彻底搞懂 Token、缓存读、补全计费机制!(附完整架构图)
人工智能·spring·缓存
Ai搬运工124 分钟前
【保姆级教程】B站缓存视频如何转为正常MP4格式?
缓存·音视频·bilibili
敲上瘾28 分钟前
高并发内存池(三):PageCache(页缓存)的实现
linux·c++·缓存·高并发内存池·池化技术
快点好好学习吧29 分钟前
CPU 从 L1/L2 缓存读取 MySQL 代码指令的庖丁解牛
android·mysql·缓存
awljwlj30 分钟前
黑马点评复习—缓存相关【包含可能的问题和基础知识复习】
java·后端·spring·缓存
XY_墨莲伊35 分钟前
【实战项目】基于B/S结构Flask+Folium技术的出租车轨迹可视化分析系统(文末含完整源代码)
开发语言·后端·python·算法·机器学习·flask
小雅痞1 小时前
[Java][Leetcode simple] 1. 两数之和
java·算法·leetcode
somi71 小时前
ARM-驱动-09-LCD FrameBuffer
arm开发·驱动开发·算法·自用