[Leetcode-460]LFU Cache 最近不常用页面交换

来源:互联网 发布:成都餐饮网络建设电话 编辑:程序博客网 时间:2024/06/10 22:18

  • 题目概要
  • 分析
  • 代码
  • 参考文献

0. 题目概要

Design and implement a data structure for Least Frequently Used (LFU) cache. It should support the following operations: get and put.
设计并实现一个数据结构,满足LFU (Least Frequently Used) Cache特性,实现两种操作:get和put

get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.

get(key) - 如果存在缓存则返回key对应的那个value正值, 否则返回-1.

put(key, value) - Set or insert the value if the key is not already present.
设置指定key的value,如果key不存在,则插入该key-value对。

When the cache reaches its capacity, it should invalidate the least frequently used item before inserting a new item.

For the purpose of this problem, when there is a tie (i.e., two or more keys that have the same frequency), the least recently used key would be evicted.

如果cache空间已满,则将最少使用的key-value对移除,如果存在多个key-value对的使用次数相同,则将上次访问时间最早的key-value对移除。。

Follow up:
Could you do both operations in O(1) time complexity?

O(1)时间复杂度实现get和put操作

Example:

LFUCache cache = new LFUCache( 2 /* capacity */ );cache.put(1, 1);cache.put(2, 2);cache.get(1);       // returns 1cache.put(3, 3);    // evicts key 2cache.get(2);       // returns -1 (not found)cache.get(3);       // returns 3.cache.put(4, 4);    // evicts key 1.cache.get(1);       // returns -1 (not found)cache.get(3);       // returns 3cache.get(4);       // returns 4

1. 分析

这道题是让我们实现最近不常用页面置换算法LFU (Least Frequently Used), 之前我们做过一道类似的题 LRU Cache ,让我们求最近最少使用页面置换算法LRU (Least Recnetly Used)。

顾名思义,LRU算法是首先淘汰最长时间未被使用的页面,而LFU是先淘汰一定时间内被访问次数最少的页面。


2. 代码

这里写图片描述

public class LFUCache {    HashMap<Integer, Integer> vals;    HashMap<Integer, Integer> counts;    HashMap<Integer, LinkedHashSet<Integer>> lists;    int cap;    int min = -1;    public LFUCache(int capacity) {        cap = capacity;        vals = new HashMap<>();        counts = new HashMap<>();        lists = new HashMap<>();        lists.put(1, new LinkedHashSet<>());    }    public int put(int key) {        if(!vals.containsKey(key))            return -1;        int count = counts.get(key);        counts.put(key, count+1);        lists.get(count).remove(key);        if(count==min && lists.get(count).size()==0)            min++;        if(!lists.containsKey(count+1))            lists.put(count+1, new LinkedHashSet<>());        lists.get(count+1).add(key);        return vals.get(key);    }    public void put(int key, int value) {        if(cap<=0)            return;        if(vals.containsKey(key)) {            vals.put(key, value);            get(key);            return;        }         if(vals.size() >= cap) {            int evit = lists.get(min).iterator().next();            lists.get(min).remove(evit);            vals.remove(evit);        }        vals.put(key, value);        counts.put(key, 1);        min = 1;        lists.get(1).add(key);    }}

参考文献

https://leetcode.com/problems/lfu-cache/description/