Leetcode 16.25 LRU缓存 哈希表与双向链表的组合

  首先,既然是缓存,哈希表是必须用到的,保证以 O(1) 时间复杂度进行查询。

  另外需要维护元素的使用顺序,不断将近期使用的元素推向前方,并在超出容量时删除末尾元素,这里使用双向链表实现对使用顺序的维护。

    class LRUCache {

        class ListNode {
            ListNode pre;
            ListNode next;
            int val;
            int key;

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

        private final int capacity;
        private final Map<Integer, ListNode> pool;
        private ListNode head;
        private ListNode last;
        private int length;

        LRUCache(int capacity) {
            this.capacity = capacity;
            pool = new HashMap<Integer, ListNode>();
            head = new ListNode(0, 0);
            last = new ListNode(0, 0);
            head.next = last;
            last.pre = head;
            length = 0;
        }


        public int get(int key) {
            if (!pool.containsKey(key)) {
                return -1;
            }
            ListNode node = pool.get(key);
            removeToHead(node);
            return node.val;
        }

        public void put(int key, int value) {
            if (pool.containsKey(key)) {
                ListNode node = pool.get(key);
                node.val = value;
                removeToHead(node);
                return;
            }
            ListNode node = new ListNode(key, value);
            addToHead(node);
            pool.put(key, node);
            length++;
            if (length > capacity) {
                pool.remove(removeLast().key);
            }
        }

        private void removeNode(ListNode node) {
            node.pre.next = node.next;
            node.next.pre = node.pre;
            node.pre = node.next = null;
        }

        private void addToHead(ListNode node) {
            node.next = head.next;
            node.pre = head;
            head.next.pre = node;
            head.next = node;
        }

        private void removeToHead(ListNode node) {
            removeNode(node);
            addToHead(node);
        }

        private ListNode removeLast() {
            ListNode node = last.pre;
            if (node == head) {
                return null;
            }
            removeNode(node);
            return node;
        }
    }

 

posted @ 2020-07-16 10:38  牛有肉  阅读(268)  评论(0编辑  收藏  举报