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

设计LRU缓存结构

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

LRU-自建双向链表

使用LinkedHashMap的同学可以歇歇了,面试你用LinkedHashMap试试:)
所以这里提供自建方案,学习自lc

import java.util.*;

public class Solution {
    // 链表节点,用于存放数据,为HashMap提供顺序
    private class Node {
        int key;
        int value;
        Node pre;
        Node next;

        public Node(){}

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

    Node head; // 头节点
    Node tail; // 尾节点
    int size;  // 容量
    int capacity; // 容量上限

    Map<Integer, Node> cache; // 方便查找节点,实现O(1)查找时间复杂度
    /**
     * lru design
     * @param operators int整型二维数组 the ops
     * @param k int整型 the k
     * @return int整型一维数组
     */
    public int[] LRU (int[][] operators, int k) {
        // write code here
        init(k);

        List<Integer> res = new ArrayList<>();
        for (int[] o : operators) {
            if (o[0] == 1) {
                set(o[1], o[2]);
            } else {
                res.add(get(o[1]));
            }
        }

        return res.stream().mapToInt(Integer::intValue).toArray();
    }
    // 初始化LRU
    private void init(int capacity) {
        this.size = 0;
        this.capacity = capacity;
        cache = new HashMap<>();
        head = new Node();
        tail = new Node();
        head.next = tail;
        tail.pre = head;
    }
    // 查找节点
    private int get(int key) {
        Node node = cache.get(key);
        if (node == null) return -1; // 不存在返回-1;

        moveToHead(node);  //存在则将节点移至链表头部
        return node.value;
    }
    // 设置节点
    private void set(int key, int value) {
        Node node = cache.get(key);

        if (node == null) { // 节点不存在,新建节点并插入链表头部和哈希表
            node = new Node(key, value);
            addToHead(node);
            cache.put(key, node);
            size++;

            if (size > capacity) { // 容量超过容量上限,则移除链表尾部,并删除对应哈希表数据
                cache.remove(tail.pre.key);
                removeNode(tail.pre);
                size--;
            }
        } else { // 节点已存在,则修改value,并将节点移至头部
            node.value = value;
            moveToHead(node);
        }
    }
    // 将链表节点移至链表头部
    private void moveToHead(Node node) {
        removeNode(node);
        addToHead(node);
    }
    // 将节点移除
    private void removeNode(Node node) {
        node.pre.next = node.next;
        node.next.pre = node.pre;
    }
    // 将节点添加至链表头部
    private void addToHead(Node node) {
        node.next = head.next;
        node.pre = head;
        node.next.pre = node;
        node.pre.next = node;
    }
}
全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务