定个小目标之刷LeetCode热题(23)

今天写这道题,背过八股文的都应该知道LRU算法缓存的基本原理,在 Java 语言中,同样有类似的数据结构 LinkedHashMap本题我们采用自己创建哈希表+双链表的形式简单实现一下

对于get操作:通过cache.get(key)获取,如果不存在则直接返回-1,否则返回对于key的value并把该结点移动到链表头部

对于put操作:通过cache.get(key)获取,如果存在则直接替换该结点的value并把该结点移动到链表头部,否则创建新的结点,把它put到chache中,然后添加到链表头部并且size++,最后判断size是否大于capacity,如果大于则需要移除链表尾部结点,并且需要移除cache中对应的结点,最后size--

代码如下

class LRUCache {
    // 双链表
    class DLinkedNode {
        int key;
        int value;
        DLinkedNode prev;
        DLinkedNode next;

        public DLinkedNode() {
        }

        public DLinkedNode(int _key, int _value) {
            key = _key;
            value = _value;
        }
    }

    // 创建哈希表
    private Map<Integer, DLinkedNode> cache = new HashMap<>();
    // 哈希表当前结点个数
    private int size;
    // 最大结点个数,不能超过此阈值,否则需要进行移除链表尾结点操作
    private int capacity;
    // 双链表伪头部和伪尾部
    DLinkedNode head, tail;

    // 传入一个int型数字构建一个LRUCache对象
    public LRUCache(int capacity) {
        this.size = 0;
        this.capacity = capacity;
        head = new DLinkedNode();
        tail = new DLinkedNode();
        head.next = tail;
        tail.prev = head;
    }

    // get操作
    public int get(int key) {
        DLinkedNode node = cache.get(key);
        if (node == null) {
            return -1;
        }
        moveToHead(node);
        return node.value;
    }

    public void moveToHead(DLinkedNode node) {
        removeNode(node);
        addToHead(node);
    }

    public void removeNode(DLinkedNode node) {
        node.next.prev = node.prev;
        node.prev.next = node.next;
    }

    public void addToHead(DLinkedNode node) {
        node.prev = head;
        node.next = head.next;
        head.next.prev = node;
        head.next = node;
    }

    // put操作
    public void put(int key, int value) {
        DLinkedNode node = cache.get(key);
        if (node == null) {
            DLinkedNode newNode = new DLinkedNode(key, value);
            cache.put(key, newNode);
            addToHead(newNode);
            size++;
            if (size > capacity) {
                DLinkedNode tail = removeTail();
                cache.remove(tail.key);
                size--;
            }
        } else {
            node.value = value;
            moveToHead(node);
        }
    }

    private DLinkedNode removeTail() {
        DLinkedNode res = tail.prev;
        removeNode(res);
        return res;
    }
}

题目链接:题单 - 力扣(LeetCode)全球极客挚爱的技术成长平台

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值