【LeetCode】LRU Cache 解题报告

题外话:才连续写了几篇博客,博客排名竟然就不再是“千里之外”了,已经进入2万名之内了。再接再厉,加油!

Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and set.

get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.
set(key, value) - Set or insert the value if the key is not already present. When the cache reached its capacity, it should invalidate the least recently used item before inserting a new item.

【题意】

设计并实现一个支持get和set操作的缓存:

get(key) - 存在时返回其值,否则返回-1;

set(key) - 不存在时插入新值,存在时更新其值,注意当容量满时,需删除最长时间没有访问的key,将其删除,并插入新的key。


==================== Map+List 实现法 ====================

【思路】

用map结构实现<key, value>的存储与读取。

用一个list来记录key被访问时间的久远,最近被访问的放在list的最后,list中的第一个key表示最长时间没被访问的。

【Java代码】

class LRUCache {
    HashMap<Integer, Integer> map;
    ArrayList<Integer> list;
    int capacity;
    
    public LRUCache(int capacity) {
        map = new HashMap<Integer, Integer>(capacity);
        list = new ArrayList<Integer>(capacity);
        this.capacity = capacity;
    }
    
    public int get(int key) {
        if (map.get(key) == null) return -1;
        list.remove(new Integer(key)); 
        list.add(key);
        return map.get(key);
    }
    
    public void set(int key, int value) {
    	if (map.get(key) != null) {//原来存在key
    		map.put(key, value);
    		list.remove(new Integer(key)); 
            list.add(key);
    	} else {//原来不存在key
    		if (map.size() < capacity) {//容量不满
    			map.put(key, value);
    			list.add(key);
    		} else {//容量满
    			int leastkey = list.remove(0);
                list.add(key);
                map.remove(leastkey);
                map.put(key, value);
    		}
    	}
    }
}

【注意点】

题目要求是Least Recently Used,不仅 set 时要更新list,get 时也要更新list。

set 时,需先判断map中有无该值,若没有再判断map是否满了;如果反过来,即先判断map是否为满,再判断map中有无该值,这样就错了。

因为如果map满时,其中有该值,直接更新就好,而先判断map是否为满的话,就会导致删除最长时间没有被访问的值。


【常规解法】

通常用一个双向链表来记录最长时间没被访问的元素,因为双向链表可以在O(1)的时间内实现将某个结点移动到表头和删除尾部结点。

上面代码中用list实现,其remove时实际上是遍历整个list来寻找某个结点的。

LeetCode没有对时间作要求,面试时肯定会被要求的。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值