zoukankan      html  css  js  c++  java
  • 算法——模拟LRU机制

    运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制 。
    实现 LRUCache 类:
    LRUCache(int capacity) 以正整数作为容量 capacity 初始化 LRU 缓存
    int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 。
    void put(int key, int value) 如果关键字已经存在,则变更其数据值;如果关键字不存在,则插入该组「关键字-值」。当缓存容量达到上限时,它应该在写入新数据之前删除最久未使用的数据值,从而为新的数据值留出空间。
    leetcode

    解题思路:利用双向链表,可以在O(1)的时间内完成末尾的删除。

    双向链表的创建思想:双向链表

    class LRUCache {
        // key -> Node(key, val)
        private HashMap<Integer, Node> map;
        // Node(k1, v1) <-> Node(k2, v2)...
        private DoubleList cache;
        // 最大容量
        private int cap;
    
        public LRUCache(int capacity) {
            this.cap = capacity;
            map = new HashMap<>();
            cache = new DoubleList();
        }
        
        public int get(int key) {
            if(!map.containsKey(key)){
                return -1;
            }
            int val = map.get(key).val;
            
            put(key, val);
            
            return val;
        }
        
        public void put(int key, int value) {
            Node x = new Node(key, value);
            
            if(map.containsKey(key)){
                cache.remove(map.get(key));
                cache.addFirst(x);
                map.put(key, x);
            }else{
                if(cap == cache.size()){
                    Node last = cache.removeLast();
                    map.remove(last.key);
                }
                cache.addFirst(x);
                map.put(key, x);
            }
        }
    }
    
    class Node {
        public int key, val;
        public Node next, prev;
        public Node(int k, int v) {
            this.key = k;
            this.val = v;
        }
    }
    
    class DoubleList {  
        private Node head, tail; // 头尾虚节点
        private int size; // 链表元素数
    
        public DoubleList() {
            head = new Node(0, 0);
            tail = new Node(0, 0);
            head.next = tail;
            tail.prev = head;
            size = 0;
        }
    
        // 在链表头部添加节点 x
        public void addFirst(Node x) {
            x.next = head.next;
            x.prev = head;
            head.next.prev = x;
            head.next = x;
            size++;
        }
    
        // 删除链表中的 x 节点(x 一定存在)
        public void remove(Node x) {
            x.prev.next = x.next;
            x.next.prev = x.prev;
            size--;
        }
        
        // 删除链表中最后一个节点,并返回该节点
        public Node removeLast() {
            if (tail.prev == head)
                return null;
             Node last = tail.prev;
            remove(last);
            return last;
        }
        
        // 返回链表长度
        public int size() { return size; }
    }
    
  • 相关阅读:
    关于 相对论 的 一些 讨论推理 杂集
    反相 大全
    收录 猴哥 对于 相对论 水星进动 星光偏折 引力透镜 GPS 的 说法
    哲学 一词 起源于 古希腊 的 “爱智慧”
    字符流的父类
    字符编码
    对象流
    BufferStream 缓存流
    OutputStream 以及 使用文件输入输出流实现文件的复制操作
    InputStream
  • 原文地址:https://www.cnblogs.com/lippon/p/14117640.html
Copyright © 2011-2022 走看看