题解 | #设计LRU缓存结构#

设计LRU缓存结构

http://www.nowcoder.com/practice/e3769a5f49894d49b871c09cadd13a61

import java.util.*;


class LRUCache {

    // 双向链表的Node,定义key/value以及prev/next指针
    public static class DoubleNode {
        DoubleNode prev;
        DoubleNode next;
        int key;
        int value;

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

        public DoubleNode() {

        }
    }

    // 缓存的Map,key-key,value-Node<key,value>
    private HashMap<Integer, DoubleNode> cache = new HashMap<>();

    // 双向链表的head
    private DoubleNode head = new DoubleNode();
    // 双向链表的tail
    private DoubleNode tail = new DoubleNode();

    // cache的容量,超过容量直接不允许放入元素了
    int capacity;

    public LRUCache(int capacity) {
        this.capacity = capacity;
        head.next = tail;
        tail.prev = head;
    }

    public int get(int key) {
        DoubleNode node = cache.get(key);
        // 如果缓存中没有的话
        if (node == null) {
            return -1;
        }
        // 如果缓存中有的话,那么移动到head地方去(先从链表中删除再移动)
        removeNode(node);
        addToHead(node);
        return node.value;
    }

    public void put(int key, int value) {
        // 对方法的容量进行判断,筛掉传递非法容量的情况
        if (capacity <= 0) {
            return;
        }
        // 从缓存中根据key拿到node
        DoubleNode node = cache.get(key);
        if (node == null) {
            // 如果缓存的容量已经满了,需要移除掉尾部的节点
            if (cache.size() == capacity) {
                cache.remove(tail.prev.key); // 必须先进行操作,不然tail.prev从链表中移除了,引用找不到了
                removeNode(tail.prev); // 必须后进行操作
            }
            // 到达这里缓存一定没满,需要新创建一个node加入到缓存和双向链表中去
            node = new DoubleNode(key, value);
            cache.put(key, node);
            addToHead(node);
            return;
        }
        // 这部分的逻辑和get是一样的,将node从链表中移除掉,并且加到链表头部去
        removeNode(node);
        addToHead(node);
        // 修改node的value为指定的value
        node.value = value;
    }

    // 将node从双向链表中移除掉,普通的双向链表的删除罢了
    private void removeNode(DoubleNode node) {
        node.prev.next = node.next;
        node.next.prev = node.prev;
    }

    // 将node添加到最前面去(因为head是傀儡节点,所以应该添加到head之后)
    private void addToHead(DoubleNode node) {
        node.next = head.next;
        node.next.prev = node;
        head.next = node;
        node.prev = head;
    }
}

public class Solution {
    /**
     * lru design
     *
     * @param operators int整型二维数组 the ops
     * @param k         int整型 the k
     * @return int整型一维数组
     */
    public int[] LRU(int[][] operators, int k) {
        LRUCache cache = new LRUCache(k);
        List<Integer> ret = new ArrayList<>();
        for (int[] operator : operators) {
            int length = operator.length;
            // 如果是get操作
            switch (length) {
                case 2:
                    int get = cache.get(operator[1]);
                    ret.add(get);
                    break;
                case 3:
                    cache.put(operator[1], operator[2]);
                    break;
            }
        }
        int[] array = new int[ret.size()];
        for (int i = 0; i < array.length; i++) {
            array[i] = ret.get(i);
        }
        return array;
    }
}
全部评论

相关推荐

01-12 14:08
门头沟学院 Java
有寒假来武汉小米总部实习的大学生嘛,我也是小米的员工,想找合租舍友,仅限女生可免租半月,二月初可入住,也就是说房租是2.15开始算的哦~也可以将行李提前放过来~房屋介绍:1、房子情况:有电梯;租的是三室一厅一卫一厨,&nbsp;但是有个卧室比较小,不打算找人,只住两个人就可以了;衣柜也很大,可以放下很多衣服;房屋采光真的很好,早上起来可以在床上晒太阳的那种,十分惬意(夏季晚上十分好看!)2.&nbsp;楼下离我们很近的地方有小吃街和一个两层大超市(大概步行两分钟多就可以走到)&nbsp;,还有一个新开的麦当劳,晚上可以去吃小吃,购买物资也可以去大超市;3.&nbsp;房子基本设施齐备(洗衣机,冰箱,空调,油烟机,热水器);4.&nbsp;我有稳定的工作,生活中很注意卫生,周末有时间会自己做饭,可以投喂哦~5.&nbsp;出行:距离公交站步行10分钟不到,距政务中心,武汉小米总部三站(晚上我都是走回来的,很近的~);一个比较进的地铁,距离大概1km左右;出入我觉得很方便;6.&nbsp;房租:1150每月,押一付二,无物业费,也没有中介费和其他额外费用。7.&nbsp;民用水电燃气,用多少交多少,水电费正常平摊。希望你是:1.&nbsp;女生(本人女),不带异性回家,如有同性朋友来玩,最多过夜一晚;2.&nbsp;爱干净,讲卫生,作息正常,不吵闹,有稳定工作;3.&nbsp;好沟通,有任何问题一定要沟通,不要闷着!中介勿扰,非诚勿扰!!!希望不要浪费彼此的时间诚心有意向的可以联系我看房
租房找室友
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务