牛客Top200 --- 设计LRU缓存结构详解

题目

在这里插入图片描述

import java.util.*;

public class Solution {
    public static void main(String[] args) {
        int[][] arr = new int[][]{{1,1,1},{1,2,2},{1,3,2},{2,1},{1,4,4},{2,2}};
        int[] lruArr = LRU(arr, 3);
        System.out.println(Arrays.toString(lruArr));
        System.out.println("---------------------");
        int[][] arr1 = new int[][]{{1,1,1},{1,2,2},{2,1},{1,3,3},{2,2},{1,4,4},{2,1},{2,3},{2,4}};
        int[] lruArr1 = LRU(arr1, 2);
        System.out.println(Arrays.toString(lruArr1));

    }
    public static int[] LRU (int[][] operators, int k){
        List<Integer> temp = new ArrayList<>();
        Map<Integer, Integer> cache = new LinkedHashMap<>();//要更新热度,删除,增加,所以用LinkedHashMap(哈希表+双向链表)
        for(int[] op : operators) {
            if (op[0] == 1) {	//opt==1
                cache.put(op[1], op[2]);
                //超出阈值k要更新缓存
                if (cache.size() > k) {
                    cache.remove(cache.keySet().iterator().next());
                }
            } else {
            	//opt==2
                Integer value = cache.get(op[1]);
                if (value != null) {
                	//更新热度
                    cache.remove(op[1]);//删除第一个key,从左往右
                    cache.put(op[1], value);//排在最后面最新,热度最高
                    temp.add(value);//结果
                } else {
                    temp.add(-1);
                }
            }
        }
        //转成数组
        int[] result = new int[temp.size()];
        for(int i=0;i<temp.size();i++) {
            result[i]=temp.get(i);
        }
        return result;
    }
}

输出
在这里插入图片描述
主要是int[] LRU (int[][] operators, int k)方法,测试通过
在这里插入图片描述

LeetCode版本

// 手动双链表 + HashMap,不取巧用LinkedHashMap
class LRUCache {
    int capacity;
    int size;
    Node head;
    Map<Integer, Node> map = new HashMap<>();

    static class Node {
        int key;
        int val;
        Node next;
        Node prev;

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

        Node remove() {
            prev.next = next;
            next.prev = prev;
            next = null;
            prev = null;
            return this;
        }

        void insert(Node node) {
            node.next = next;
            node.prev = this;
            next.prev = node;
            next = node;
        }
    }

    public LRUCache(int capacity) {
        this.capacity = capacity;
        head = new Node();
        head.next = head;
        head.prev = head;
    }
    
    public int get(int key) {
        Node node = map.get(key);
        if (node == null) return -1;

        node = node.remove();
        head.insert(node);
        return node.val;
    }
    
    public void put(int key, int value) {
        Node node = map.get(key);
        if (node == null) {
            node = new Node(key, value);
            map.put(key, node);
            size++;
        } else {
            node = node.remove();
            node.val = value;
        }

        head.insert(node);
        if (size > capacity) {
            Node removed = head.prev.remove();
            map.remove(removed.key);
            size--;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小样x

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值