LRU缓存——leetcode134

LRU缓存

描述

请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。实现 LRUCache 类:

  • LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存
  • int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 。
  • void put(int key, int value) 如果关键字 key 已经存在,则变更其数据值 value ;如果不存在,则向缓存中插入该组 key-value 。如果插入操作导致关键字数量超过 capacity ,则应该 逐出 最久未使用的关键字。

函数 get 和 put 必须以 O(1) 的平均时间复杂度运行。

样例

输入:
LRUCache(2)
set(2, 1)
set(1, 1)
get(2)
set(4, 1)
get(1)
get(2)
输出:[1,-1,1]

题解:Map+List

Map: 存储key-value

LinkedList: 按最近最先使用存储key值。数据结构:[新值,较新值,旧值],利用addFirst使得头部的值最新

image-20220527135201650
class LRUCache0 {
    private Map<Integer, Integer> nums;
    private LinkedList<Integer> list;
    private int capacity;

    public LRUCache0(int capacity) {
        nums = new HashMap<>();
        list = new LinkedList<>();
        this.capacity = capacity;
    }

    /**
     * 获取数据:
     * @param key 数据key
     * @return 如果存在key,则返回value,否则返回-1
     */
    public int get(int key) {
        if(!nums.containsKey(key)) return -1;
        list.remove(Integer.valueOf(key));
        list.addFirst(key);

        return nums.get(key);
    }

    /**
     * 写入数据:
     * 1. 没有key,则插入数值
     * 2. 如果有key, 则更新value
     * 2. 如果缓存到达上限,则删除最近最少使用的数据,在插入
     * @param key 数据key
     * @param value 数据值
     */
    public void set(int key, int value) {
        if(nums.containsKey(key)) {
            nums.put(key, value);
            list.remove(Integer.valueOf(key));
            list.addFirst(key);
        }else {
            if(list.size() == capacity) {
                Integer dKey = list.remove(list.size() - 1);
                nums.remove(dKey);
            }
            nums.put(key,value);
            list.addFirst(key);
        }
    }
}

题解: LinkedHashMap

LinkedHashMap: 有序的Map, 即可以存key-value,又可以有序取值。

数据结构: [旧值,较新值,新值], 利用put将最新的值放在最后

image-20220527135351166
class LRUCache {
    private LinkedHashMap<Integer, Integer> nums;
    private int capacity;

    public LRUCache(int capacity) {
        this.capacity = capacity;
        nums = new LinkedHashMap<>();
    }

    public int get(int key) {
        if(!nums.containsKey(key)) return -1;

        int value = nums.remove(key);
        nums.put(key, value);

        return value;
    }

    public void set(int key, int value) {
        if(nums.containsKey(key)) {
            nums.remove(key);
            nums.put(key, value);
        }else {
            if(nums.size() == capacity) {
                nums.remove(nums.keySet().iterator().next());
            }

            nums.put(key, value);
        }
    }
}
posted @ 2022-05-27 13:56  言思宁  阅读(25)  评论(0编辑  收藏  举报