LRU缓存(Leetcode146)

例题:
分析:

题目要求函数get和put要达到O(1)的时间复杂度,可以用 hashMap 来实现,因为要满足逐出最久未使用的元素的一个效果,还需要配合一个双向链表来共同实现。链表中的节点为一组key-value。

我们可以用双向链表来储存数据(key-value),当调用put方法添加数据时,可以将数据(key-value)添加到双向链表的队头,队头的元素表示最新使用的元素,越靠近队尾,就是最久未用的元素。

当调用get方法时,若存在此元素,则从双向链表中把该组数据(key-value)提到队头来。

代码实现:
java 复制代码
package leetcode;

import java.util.HashMap;

public class LRUCacheLeetcode146 {

    static class LRUCache {

        static class Node{
            Node next;
            Node prev;
            int key;
            int value;
            public Node(){

            }

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

        static class DoublyLinkedList{
            Node head;
            Node tail;

            public DoublyLinkedList() {
                head = tail = new Node();
                head.next = tail;
                tail.prev = head;
            }

            //头部添加 head<->1<->2<->tail    假如添加3
            public void addFirst(Node newNode){
                Node oldFirst = head.next;
                oldFirst.prev = newNode;
                head.next = newNode;
                newNode.prev = head;
                newNode.next = oldFirst;
            }

            //已知节点删除  head<->1<->2<->tail  假如删除2
            public void remove(Node node){
                Node prev = node.prev;
                Node next = node.next;
                prev.next = next;
                next.prev = prev;
            }

            //尾部删除
            public Node removeLast(){
                Node last = tail.prev;
                remove(last);
                return last;
            }
        }

        private final HashMap<Integer, Node> map = new HashMap<>();
        private final DoublyLinkedList list = new DoublyLinkedList();
        private final int capacity;
        public LRUCache(int capacity) {
            this.capacity = capacity;
        }

        public int get(int key) {
            if(!map.containsKey(key)){
                return -1;
            }
            Node node = map.get(key);
            //hash表中存在该数据,改组数据应放到队头
            //先从中删除原始数据
            list.remove(node);
            //再将改组数据添加到队头
            list.addFirst(node);
            return node.value;
        }

        public void put(int key, int value) {
            if(map.containsKey(key)){ //更新
                Node node = map.get(key);
                node.value = value;
                list.remove(node);
                list.addFirst(node);
            }else{ //添加
                Node newNode = new Node(key, value);
                map.put(key, newNode);
                list.addFirst(newNode);
                if(map.size() > capacity){
                    Node removed = list.removeLast();
                    //删除hash表中的数据
                    map.remove(removed.key);
                }
            }
        }
    }

    public static void main(String[] args) {
        LRUCache cache = new LRUCache(2);
        cache.put(1, 1);
        cache.put(2, 2);
        System.out.println(cache.get(1)); // 1
        cache.put(3, 3);
        System.out.println(cache.get(2)); // -1
        cache.put(4, 4);
        System.out.println(cache.get(1)); // -1
        System.out.println(cache.get(3)); // 3
    }
}
相关推荐
江畔柳前堤3 小时前
大语言模型分布式训练:从并行策略到万卡工程的系统梳理
人工智能·分布式·深度学习·算法·目标检测·机器学习·语言模型
Forever Nore4 小时前
LeetCode 4 寻找两个正序数组的中位数 - 二分
算法·leetcode
罗西的思考6 小时前
【OpenClaw具身硬件】MiniClaw 阅读笔记---(1)基础
人工智能·算法·机器学习
蛋先生DX7 小时前
大模型参数存储格式揭秘:BF不是男朋友
深度学习·算法·llm
爱跳舞的烤冷面7 小时前
自学嵌入式第22天(数据结构——哈希)
数据结构·算法·哈希算法
猎嘤一号8 小时前
博弈论(Game Theory)的理论、算法与工程
人工智能·算法·安全·博弈论
月光船幽幽8 小时前
影子模式下保护 logits 不被修改
人工智能·python·算法
马拉AI8 小时前
腾讯开源 Agent 记忆系统,AI“换对话就忘”的问题有了新解法(附安装使用教程)
人工智能·算法·开源·科研
地平线开发者9 小时前
征程6工具链模型X86推理方式说明
算法
地平线开发者10 小时前
【征程6】校准量化中HistogramObserver解析
算法