Leetcode每日一题-146(5.25-java版本)

运用你所掌握的数据结构,设计和实现一个  LRU (最近最少使用) 缓存机制。它应该支持以下操作: 获取数据 get 和 写入数据 put 。
获取数据 get(key) - 如果密钥 (key) 存在于缓存中,则获取密钥的值(总是正数),否则返回 -1。
写入数据 put(key, value) - 如果密钥已经存在,则变更其数据值;如果密钥不存在,则插入该组「密钥/数据值」。当缓存容量达到上限时,它应该在写入新数据之前删除最久未使用的数据值,从而为新的数据值留出空间。
进阶:
你是否可以在 O(1) 时间复杂度内完成这两种操作?
方法一:
比较暴力直接用LinkedHashMap。
class LRUCache {
    
    LinkedHashMap<Integer,Integer> map = new LinkedHashMap<>();
    int capacity;
    
    public LRUCache(int capacity) {
        this.capacity = capacity;
    }
    
    public int get(int key) {
        if(!map.containsKey(key))
            return -1;
        int res = map.get(key);
        map.remove(key);
        map.put(key,res);
        return res;
    }
    
    public void put(int key, int value) {

        if(map.containsKey(key)){
            map.remove(key);
            map.put(key,value);
            return;
        }
           
        if(capacity==0){
            map.remove(map.entrySet().iterator().next().getKey()); 
        }else{
            capacity--;
        }
    
        map.put(key,value);
    }
}
方法二:
方法二采用双向链表 加 hashmap,hashmap中存储(key,node),双向链表的尾部代表新加入的节点,头部表示可能过期的节点。
class LRUCache {

    HashMap<Integer,Node>map = new HashMap<>();
    int capacity;
    Node head,tail;

    class Node{
        int key,value;
        Node pre,next;
        public Node(int key,int value){
            this.key = key;
            this.value = value;
        }
    }

    //节点加入队列末尾
    public void add(Node node){
        node.next = tail;
        node.pre = tail.pre;
        tail.pre.next = node;
        tail.pre = node;
    }

    //删除当前节点
    public void del(Node node){
        node.pre.next = node.next;
        node.next.pre = node.pre;
    }

    public LRUCache(int capacity) {
        this.capacity = capacity;
        head = new Node(0,0);
        tail = new Node(0,0);
        head.next = tail;
        tail.pre = head;
        
    }
    
    public int get(int key) {
        Node node = map.get(key);
        if(node == null)
        return -1;
        if(node.next != tail){
            del(node);  
            add(node);   
        }
        return node.value;
    }
    
    public void put(int key, int value) {
        Node temp =map.get(key);
        if(temp!=null){
            if(temp.next != tail){
            del(temp);
            temp.value = value;
            map.put(key,temp);   
            add(temp);
            return;   
            }
            tail.pre.value = value;
            return;
        }
        if(capacity==0){
            Node node1 = head.next;
            map.remove(node1.key);
            del(node1);
        }else{
            capacity--;
        }
        Node node = new Node(key,value);
        map.put(key,node);
        add(node);
    }   
}




#leetcode##笔试题目#
全部评论

相关推荐

等闲_:感觉有好多地方会被问穿,mysql存储向量这个方案问题应该很大的,如果深问的的话,为什么不用es,不用pg,不用mivus,分块策略是怎么做的,向量化是怎么向量化的,稠密向量还是稀疏向量,再深问余弦相似度,HSWM算法,Bm25算法,为什么不用混合检索或者Rank重排序优化?其他的项目不停机分库分表咋实现的,切库过程中数据有diff的话有没有补偿策略?既然有了分库分表了有没有碰到业务上不好优化的慢sql,让这个sql读从库?而且点评的话,最好自己压测过,要不这个数据也不好解释。现在就27的情况来看,很多同学已经有了中大厂实习,这个节点也会偏向这些有大厂实习的92同学,而且hc也不多,所以坚持海投吧
听劝,我这个简历该怎么改...
点赞 评论 收藏
分享
评论
2
1
分享

创作者周榜

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