leetcode146.LRU缓存

发布于:2025-04-05 ⋅ 阅读:(36) ⋅ 点赞:(0)

思路源自

【面试高频】146. LRU 缓存

 采用哈希表+双向链表

put一个键值对时,采用头插法将缓存块置于等级较高的位置,如果put数量超出限制,那么就将尾部的缓存块删除,以此达到置换的一个效果

get一个键值对也是同样的思路,如果不命中直接返回-1,如果命中先删除缓存块再头插缓存块,这样就达到了访问后更新缓存块等级的目的

class LRUCache {

    class DoubleLinkedNode {
        DoubleLinkedNode pre;
        int key;
        int value;
        DoubleLinkedNode next;

        public DoubleLinkedNode() {
            key=-1;
            value=-1;
        }

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

    private int size;
    private int capacity;
    private Map<Integer,DoubleLinkedNode> cache;
    DoubleLinkedNode head;
    DoubleLinkedNode tail;

    //初始化两个虚拟节点,头尾指针互指
    public LRUCache(int capacity) {
        this.size=0;
        this.capacity=capacity;
        this.cache = new HashMap<>();
        this.head = new DoubleLinkedNode();
        this.tail = new DoubleLinkedNode();
        head.pre=null;
        head.next=tail;
        tail.pre=head;
        tail.next = null;
    }

    //获取缓存中的值,如果命中要更新缓存
    public int get(int key) {
        if (cache.containsKey(key)) {
            DoubleLinkedNode doubleLinkedNode = cache.get(key);
            this.delete(doubleLinkedNode.key);
            this.add(doubleLinkedNode.key, doubleLinkedNode.value);
            return doubleLinkedNode.value;
        } else {
            return -1;
        }
    }

    //缓存添加或者置换
    public void put(int key, int value) {
        if (cache.containsKey(key)) {
            this.delete(key);
            this.add(key, value);
        } else {
            if (this.capacity == this.size) {
                this.delete(tail.pre.key);
            }
            this.add(key, value);
        }
    }

    //新增一个新的缓存,采用头插法
    private void add(int key, int value) {
        DoubleLinkedNode doubleLinkedNode = new DoubleLinkedNode(key, value);
        doubleLinkedNode.pre=this.head;
        doubleLinkedNode.next=this.head.next;
        this.head.next.pre=doubleLinkedNode;
        this.head.next=doubleLinkedNode;
        this.size++;
        cache.put(key, doubleLinkedNode);
    }

    //删除一个现有缓存
    private void delete(int key) {
        DoubleLinkedNode doubleLinkedNode = cache.get(key);
        doubleLinkedNode.pre.next=doubleLinkedNode.next;
        doubleLinkedNode.next.pre = doubleLinkedNode.pre;
        this.size--;
        cache.remove(key);
    }
}

/**
 * Your LRUCache object will be instantiated and called as such:
 * LRUCache obj = new LRUCache(capacity);
 * int param_1 = obj.get(key);
 * obj.put(key,value);
 */


网站公告

今日签到

点亮在社区的每一天
去签到