HashMap+双向链表实现LRU算法

请你设计并实现一个满足  LRU (最近最少使用) 缓存 约束的数据结构。

实现 LRUCache 类:

  • LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存
  • int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 。
  • void put(int key, int value) 如果关键字 key 已经存在,则变更其数据值 value ;如果不存在,则向缓存中插入该组 key-value 。如果插入操作导致关键字数量超过 capacity ,则应该 逐出 最久未使用的关键字。

函数 get 和 put 必须以 O(1) 的平均时间复杂度运行。

class LRUCache {
    // LRU缓存 最近最少使用---思路:用双链表来模拟,HashMap来
    int capacity;   //容量
    DoubleList cache;
    HashMap<Integer,Node> map;

    //初始化
    public LRUCache(int capacity) {
        this.capacity = capacity;
        cache = new DoubleList();
        map = new HashMap<>();
    }
    
    //如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1
    public int get(int key) {
        if(map.containsKey(key)){
            //如果存在,调整顺序
            Node tempNode =  map.get(key);
            cache.remove(tempNode);
            cache.addLast(tempNode);
            return tempNode.val;
        }else{
            return -1;
        }
    }
    //如果关键字 key 已经存在,则变更其数据值 value ;如果不存在,则向缓存中插入该组 key-value
    public void put(int key, int value) {
        if(map.containsKey(key)){
            //如果存在
            Node tempNode = map.get(key);
            cache.remove(tempNode);
            Node newNode = new Node(key,value);
            map.put(key,newNode);
            cache.addLast(newNode);
        }else{
            //如果不存在
            //判断满了没有
            if(map.size()==capacity){
                //满了--删除最久没访问的
                Node first = cache.removeFirst();
                map.remove(first.key);
                //再新添加
            }
            //如果没满
            Node node = new Node(key,value);
            map.put(key,node);
            cache.addLast(node);

            }  
    }
    //定义双向链表的节点
    class Node{
        int key;
        int val;
        Node pre;
        Node next;
        //构造
        public Node(int key,int val){
            this.key = key;
            this.val = val;
        }
    }
    //定义双向链表
    class DoubleList{
        int size;
        Node head,tail;

        public DoubleList(){
            //初始化链表
            head = new Node(0,0);
            tail = new Node(0,0);
            head.next = tail;
            tail.pre = head;
            size = 0;
        }

        //末尾添加节点
        public void addLast(Node x){
            tail.pre.next = x;
            x.pre=tail.pre;
            x.next = tail;
            tail.pre = x;
            size++;
        }
        //删除最近没访问的节点并且返回这个节点--head是虚拟头节点
        public Node removeFirst(){
            Node first = head.next;
            head.next = head.next.next;
            head.next.pre=head;
            size--;
            return first;
        }

        //删除指定节点
        public void remove(Node node){
            node.pre.next=node.next;
            node.next.pre=node.pre;
            size--;

        }
    }
}

/**
 * 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);
 */

全部评论
mark一下大佬
1 回复 分享
发布于 02-21 23:21 河南
核心就一句话,链表负责顺序,map负责映射
点赞 回复 分享
发布于 03-31 14:30 上海

相关推荐

看新闻上说,印度媒体都在密集发申请攻略,咨询量直接涨了30%印度、韩国、新加坡的申请意愿特别突出,感觉要成科技人才的新选择了~我的offer还没有呢!
ysb:哥们就不明白了,自己的人才都留不住,然后找外国,咋滴给外国人才高福利朝九晚五不加班是吗,然后我们大学生996,加班,无offer,摆地摊,送外卖是吗,有点意思,很英明
我的秋招日记
点赞 评论 收藏
分享
否极泰来来来来:解约赔多少
点赞 评论 收藏
分享
评论
2
2
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务