LRU(最近最少使用)缓存算法LeetCode146

文章总结的思路参考(图我也是白嫖的)

https://www.bilibili.com/video/BV1hp4y1x7MH

  1. 要求在O(1)的时间复杂度完成get操作,我们想到的数据结构是Map。但是,put操作是需要记录下来哪个是(最近最少使用)需要被删除更新的键,Map做不到。
  2. 插入和删除的操作时间复杂度都是O(1)的,我们自然想到的数据结构就是链表。但是问题就出现在查找的操作了,链表的查找时间复杂度是O(n)。
  3. 总结一下就是查找用Map,插入用双向链表。
    在这里插入图片描述

AC代码

public class LRUCache {

    HashMap<Integer,Node> map;
    DoubleLinkledLst cache;
    int capacity;

    public LRUCache(int capacity){
        map=new HashMap<Integer, Node>();
        cache=new DoubleLinkledLst();
        this.capacity=capacity;
    }

    public void put(int key,int val){
        Node newNode=new Node(key, val);
        if(map.containsKey(key)){
            cache.delete(map.get(key));
            cache.addFirst(newNode);
            map.put(key,newNode);
        }else {//如果map里没有该key
            if(map.size()==capacity) {//满了就删
                int k = cache.deleteLast();//删除链表队尾的最近最少使用的元素
                map.remove(k);
            }
                cache.addFirst(newNode);//加到双向链表头部作为最近使用的缓存
                map.put(key,newNode);
            }
        }

    public int get(int key){
        if(!map.containsKey(key)) return -1;
        int val=map.get(key).val;
        put(key,val);//查看过需要再放到头节点
        return val;
    }
}

//head是最近使用,tail是最近最少使用
class DoubleLinkledLst{
    Node head;//头节点
    Node tail;//尾节点

    public DoubleLinkledLst(){
        head=new Node(0,0);
        tail=new Node(0,0);
        //建立连接
        head.next=tail;
        tail.pre=head;
    }

    //加在头节点的后一个位置上
    public void addFirst(Node newNode){

        newNode.next=head.next;//新节点的next指针指向head节点的下一个节点
        newNode.pre=head;//新节点的pre指针指向head节点

        head.next.pre=newNode;//使原本头节点的下一个节点的pre指针指向先节点
        head.next=newNode;//head节点的next指向新节点
    }
    //删除双向链表的某一个节点
    public int delete(Node n){
        int key=n.key;
        n.next.pre=n.pre;
        n.pre.next=n.next;
        return key;
    }
    //删除最后一个节点
    public int deleteLast(){
        if(head.next==tail) return -1;
        return delete(tail.pre);
    }
}

class Node{
    int key;
    int val;
    Node pre;
    Node next;
    public Node(int key,int val){
        this.key=key;
        this.val=val;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值