146. LRU 缓存机制

运用你所掌握的数据结构,设计和实现一个  LRU (最近最少使用) 缓存机制 。
实现 LRUCache 类:

LRUCache(int capacity) 以正整数作为容量 capacity 初始化 LRU 缓存
int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 。
void put(int key, int value) 如果关键字已经存在,则变更其数据值;如果关键字不存在,则插入该组「关键字-值」。当缓存容量达到上限时,它应该在写入新数据之前删除最久未使用的数据值,从而为新的数据值留出空间。

进阶:你是否可以在 O(1) 时间复杂度内完成这两种操作?

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/lru-cache
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

自定义

import java.util.HashMap;
import java.util.Map;

class LRUCache {

    private int capacity;

    private LinkedHashMap cache;

    static class Node {
        Node prev;
        Node next;
        int key;
        int value;

        public Node() {
        }

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

    static class LinkedList {
        Node head;
        Node tail;

        public LinkedList() {
            this.head = new Node();
            this.tail = new Node();
            head.next = tail;
            tail.prev = head;
        }

        public void offerLast(Node node) {
            node.next = tail;
            node.prev = tail.prev;
            tail.prev.next = node;
            tail.prev = node;
        }

        public void remove(Node node) {
            node.prev.next = node.next;
            node.next.prev = node.prev;
        }

        public Node peekFirst() {
            if (head.next == tail) {
                return null;
            }
            return head.next;
        }

        public Node pollFirst() {
            if (head.next == tail) {
                return null;
            }
            Node node = head.next;
            remove(head.next);
            return node;
        }
    }

    static class LinkedHashMap {
        Map<Integer, Node> map;

        LinkedList linkedList;

        public LinkedHashMap() {
            this.map = new HashMap<>();
            this.linkedList = new LinkedList();
        }

        public int size() {
            return map.size();
        }

        public Node peekFirst() {
            return linkedList.peekFirst();
        }

        public Node removeFirst() {
            Node node = linkedList.peekFirst();
            if (node == null) {
                return null;
            }
            linkedList.remove(node);
            map.remove(node.key);
            return node;
        }

        public Node remove(int key) {
            if (!map.containsKey(key)) {
                return null;
            }
            Node node = map.get(key);
            map.remove(key);
            linkedList.remove(node);
            return node;
        }

        public boolean containsKey(int key) {
            return map.containsKey(key);
        }

        public int get(int key) {
            if (!map.containsKey(key)) {
                return -1;
            }
            Node node = map.get(key);
            linkedList.remove(node);
            linkedList.offerLast(node);
            return node.value;
        }

        public void put(int key, int value) {
            if (map.containsKey(key)) {
                Node node = map.get(key);
                node.value = value;
                linkedList.remove(node);
                linkedList.offerLast(node);
            } else {
                Node node = new Node(key, value);
                linkedList.offerLast(node);
                map.put(key, node);
            }
        }
    }

    public LRUCache(int capacity) {
        this.capacity = capacity;
        this.cache = new LinkedHashMap();
    }

    public int get(int key) {
        if (cache.containsKey(key)) {
            return cache.get(key);
        }
        return -1;
    }

    public void put(int key, int value) {
        if (cache.containsKey(key)) {
            cache.remove(key);
            cache.put(key, value);
        } else {
            if (cache.size() == capacity) {
                cache.removeFirst();
            }
            cache.put(key, value);
        }
    }
}

/**
 * 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);
 */

LinkedHashMap

import java.util.Iterator;
import java.util.LinkedHashMap;

class LRUCache {

    private int capacity;

    private LinkedHashMap<Integer, Integer> cache;

    public LRUCache(int capacity) {
        this.capacity = capacity;
        this.cache = new LinkedHashMap<>(16, 0.75f, true);
    }

    public int get(int key) {
        if (cache.containsKey(key)) {
            return cache.get(key);
        }
        return -1;
    }

    public void put(int key, int value) {
        if (cache.containsKey(key)) {
            cache.remove(key);
            cache.put(key, value);
        } else {
            if (cache.size() == capacity) {
//                Iterator<Integer> iterator = cache.keySet().iterator();
//                iterator.next();
//                iterator.remove();
                Integer next = cache.keySet().iterator().next();
                cache.remove(next);
            }
            cache.put(key, value);
        }
    }
}

/**
 * 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);
 */
posted @ 2021-12-07 21:32  Tianyiya  阅读(18)  评论(0)    收藏  举报