[Java版本]手写LRU(Deque+哈希)/(手写双向链表+哈希)

这段代码展示了如何利用Java实现一个基于双端队列(Deque)和HashMap的数据结构,用于实现LRU(最近最少使用)缓存策略。当缓存满时,会移除最不常使用的元素。此外,还提供了一个基于双向链表的实现方式,同样遵循LRU原则。这两个实现都包括`get`和`set`操作,确保高效的缓存访问和更新。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

内部API调用

class Solution {
    Deque<Integer> deque = new LinkedList<>();
    HashMap<Integer, Integer> hashMap = new HashMap<>();
    int size;

    public Solution(int capacity) {
        size = capacity;
    }

    public int get(int key) {
        if (hashMap.containsKey(key)) {
            //更新顺序
            Integer value = hashMap.get(key);
            deque.remove(key);
            deque.offerFirst(key);
            return value;
        } else {
            return -1;
        }
    }

    public void set(int key, int value) {
        if (deque.size() < size) {
            hashMap.put(key, value);
            deque.offerFirst(key);//放最前面
        } else {//内存不够了
            if (hashMap.containsKey(key)) {//去重
                hashMap.put(key, value);
                deque.remove(key);
                deque.offerFirst(key);
            } else {//内存不够,且不重复的情况下
                Integer pollLast = deque.pollLast();//最后一个弹了
                hashMap.remove(pollLast);
                hashMap.put(key, value);
                deque.offerFirst(key);
            }
        }
    }
}

不过面试的时候一般要求手写双端队列

代码略长,但思路清晰

class Solution {
    class MyLinkedList {
        int key;
        int val;
        MyLinkedList pre;
        MyLinkedList next;
        public MyLinkedList() {
        }
        public MyLinkedList(int key, int val) {
            this.key = key;
            this.val = val;
        }
    }

    int MyLinkedListSize;//记录队列大小尺寸
    int capacity;//总大小
    private MyLinkedList head;
    private MyLinkedList tail;
    HashMap<Integer, MyLinkedList> hashMap = new HashMap<>();

    public Solution(int capacity) {
        this.MyLinkedListSize = 0;
        this.capacity = capacity;
        head = new MyLinkedList();//初始化
        tail = new MyLinkedList();
        head.next = tail;//双向链表绑定
        tail.pre = head;
    }

    public int get(int key) {
        if (hashMap.containsKey(key)) {
            int val = hashMap.get(key).val;
            moveToHead(hashMap.get(key));
            return val;
        } else return -1;
    }

    public void set(int key, int value) {
        if (MyLinkedListSize < capacity) {//去重
            if (hashMap.containsKey(key)) {
                MyLinkedList node = hashMap.get(key);
                node.val = value;
                moveToHead(node);
                hashMap.put(key, node);
            } else {
                MyLinkedList node = new MyLinkedList(key, value);
                moveToHead(node);
                hashMap.put(key, node);
                MyLinkedListSize++;
            }
        } else {
            if (hashMap.containsKey(key)) {
                MyLinkedList node = hashMap.get(key);
                node.val = value;
                moveToHead(node);
                hashMap.put(key, node);
            } else {
                int tailKey = removeTailNode();
                hashMap.remove(tailKey);//最后一个值
                MyLinkedList node = new MyLinkedList(key, value);
                addToHead(node);
                hashMap.put(key, node);
            }
        }
    }

    private void addToHead(MyLinkedList node) {
        //先连接后面
        head.next.pre = node;
        node.next = head.next;
        //再连接前面
        node.pre = head;
        head.next = node;
    }

    private void removeNode(MyLinkedList node) {
        //断开再接上
        node.pre.next = node.next;
        node.next.pre = node.pre;
    }

    private int removeTailNode() {//不用传,因为不知道最后一个是什么用tail去取就行
        MyLinkedList node = tail.pre;
        removeNode(node);
        return node.key;
    }

    private void moveToHead(MyLinkedList node) {
        //先删除再再增加
        if (hashMap.containsKey(node.key)) {
            removeNode(node);
        }
        addToHead(node);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值