【LeetCode】146、LRU缓存机制

题目:146. LRU缓存机制  、面试题 16.25. LRU缓存

题目描述:

  运用你所掌握的数据结构,设计和实现一个 LRU (Least Recently Used,最近最少使用) 缓存机制。它应该支持以下操作: 获取数据 get 和 写入数据 put ,时间复杂度要求为O(1).

  • 获取数据 get(key) - 如果密钥 (key) 存在于缓存中,则获取密钥的值(总是正数),否则返回 -1。

  • 写入数据 put(key, value) - 如果密钥不存在,则写入其数据值。当缓存容量达到上限时,它应该在写入新数据之前删除最久未使用的数据值,从而为新的数据值留出空间。


解题思路:哈希表+双向链表

  LRU是Least Recently Used的简称,代表最近最少使用算法。对于get和put方法,实际上我们只需要取出对应的值和将键值对写入缓存即可,但是,关键的是如何组织数据空间,比如当缓存已满时,淘汰策略应该是最近最少使用的先删除。因此,需要对数据进行合理的组织。

  所谓最近最少使用,当缓存容量已满时,需要选择那个最近最少使用的数据,将其删除,从而空出缓存空间。

  该算法我们使用哈希表和双向链表两个数据结构来实现。其中哈希表主要用来保存键值对对应关系,而数据是否最近被使用过用一个双向链表来记录,排在双向链表靠前的代表最近刚被使用过,而排在后面的代表很久未使用,因此删除时从双向链表后端依次删除。

代码实现:

class LRUCache {
    private Map<Integer,Integer> map;   
    private LinkedList<Integer> list;
    private int sizeOfcache;
    public LRUCache(int capacity) {
        map=new HashMap<>();   //哈希表用于存储数据
        list=new LinkedList<>();   //双向链表保存最近最少使用这一关系
        this.sizeOfcache=capacity;  //缓存容量
    }
    
    public int get(int key) {
        if(map.containsKey(key)){
            list.remove(Integer.valueOf(key)); //先从链表中删除
            list.addFirst(key);  //表示刚被访问过,越靠后表示最近最少使用的
            return map.get(key);
        }
        return -1;
    }
    
    public void put(int key, int value) {
        if(map.containsKey(key))  //已经存在,删掉
            list.remove(Integer.valueOf(key));
        else if(list.size()==sizeOfcache){  //不存在,且缓冲已满,删掉最后那个
            int keyToRemove=list.removeLast();
            map.remove(keyToRemove);
        }
        list.addFirst(key);
        map.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);
 */

猜你喜欢

转载自www.cnblogs.com/gzshan/p/12567621.html