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);
 */
相关推荐
利威尔xu10 小时前
Go IM 源码实战(14):本地缓存快 3000 倍,失效却难 10 倍
后端·缓存·微服务·面试·golang
ZhengEnCi10 小时前
GPT-6 Astra 爆改 Qwen 权重真有那么神吗:权重空间编程 0.016% 参数的真相
算法·架构
罗西的思考11 小时前
【轻量化复刻大模型 / KIMI K3】KDA(Kimi Delta Attention):并行
人工智能·算法·机器学习
夜不会漫长13 小时前
C++:红黑树
数据结构·算法
文丑颜不良啊13 小时前
LeetCode1661~1680题目解析
java·leetcode
AI备案指南-满满13 小时前
算法备案审核不通过,一般是什么原因?
java·人工智能·算法·大模型备案·算法备案·大模型登记
Ramble_Naylor14 小时前
Rust深度解读:Send 与 Sync 的本质与线程安全边界
python·算法·rust
秋天的怀念_David14 小时前
算法一千零一夜 · 第二十三夜 电力民生写成的曲线
java·程序人生·算法
不一样的故事12614 小时前
NB/T 47013.8-2015 附录D 吸枪技术
人工智能·经验分享·算法
通问AI14 小时前
用 200 行 Python 给文档库做「上下文完整度」自检:四个可复算的检查项
算法