zoukankan      html  css  js  c++  java
  • LeetCode 460. LFU Cache

    原题链接在这里:https://leetcode.com/problems/lfu-cache/

    题目:

    Design and implement a data structure for Least Frequently Used (LFU) cache. It should support the following operations: getand put.

    get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.
    put(key, value) - Set or insert the value if the key is not already present. 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.

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

    Example:

    LFUCache cache = new LFUCache( 2 /* capacity */ );
    
    cache.put(1, 1);
    cache.put(2, 2);
    cache.get(1);       // returns 1
    cache.put(3, 3);    // evicts key 2
    cache.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 3
    cache.get(4);       // returns 4

    题解:

    去掉least frequently used element, 就需要一个min来maintain到目前最不被利用的元素的利用次数.

    用三个map, 一个是维护正常key value pair的HashMap<Integer, Integer> keyVals.

    第二个是维护每个key的使用次数.

    第三个是维护每个count下对应的key set.

    当put第一个元素时, min=1, 对应更新keyVals, keyCounts 和 countKeySets.

    get时, key的count要加一, 对应调整keyCounts 和 countKeySets. 若这个key的count恰巧是最少使用次数的最后一个值,那么最少使用次数min++.

    在达到capacity后在加新key时利用min来找到least frequently used element, 并对应调整keyVals, keyCounts 和 countKeySets.

    Note: corner case capacity <= 0.

    countToKeys need LinkedHashSet, because when there is even, evict the oldest one.

    Time Complexity: get, O(1). put, O(1).

    Space: O(n).

    AC Java:

     1 public class LFUCache {
     2     HashMap<Integer, Integer> keyVals;
     3     HashMap<Integer, Integer> keyCounts;
     4     HashMap<Integer, LinkedHashSet<Integer>> countKeySets;
     5     int capacity;
     6     int min;
     7 
     8     public LFUCache(int capacity) {
     9         this.capacity = capacity;
    10         this.min = -1;
    11         keyVals = new HashMap<Integer, Integer>();
    12         keyCounts = new HashMap<Integer, Integer>();
    13         countKeySets = new HashMap<Integer, LinkedHashSet<Integer>>();
    14         countKeySets.put(1, new LinkedHashSet<Integer>());
    15     }
    16     
    17     public int get(int key) {
    18         if(!keyVals.containsKey(key)){
    19             return -1;
    20         }
    21         int count = keyCounts.get(key);
    22         keyCounts.put(key, count+1);
    23         countKeySets.get(count).remove(key);
    24         if(count == min && countKeySets.get(count).size() == 0){
    25             min++;
    26         }
    27         if(!countKeySets.containsKey(count+1)){
    28             countKeySets.put(count+1, new LinkedHashSet<Integer>());
    29         }
    30         countKeySets.get(count+1).add(key);
    31         return keyVals.get(key);
    32     }
    33     
    34     public void put(int key, int value) {
    35         if(capacity <= 0){
    36             return;
    37         }
    38         
    39         if(keyVals.containsKey(key)){
    40             keyVals.put(key, value);
    41             get(key);
    42             return;
    43         }
    44         if(keyVals.size() >= capacity){
    45             int leastFreq = countKeySets.get(min).iterator().next();
    46             keyVals.remove(leastFreq);
    47             keyCounts.remove(leastFreq);
    48             countKeySets.get(min).remove(leastFreq);
    49         }
    50         keyVals.put(key, value);
    51         keyCounts.put(key, 1);
    52         countKeySets.get(1).add(key);
    53         min = 1;
    54     }
    55 }
    56 
    57 /**
    58  * Your LFUCache object will be instantiated and called as such:
    59  * LFUCache obj = new LFUCache(capacity);
    60  * int param_1 = obj.get(key);
    61  * obj.put(key,value);
    62  */

    类似LRU CacheAll O`one Data Structure.

  • 相关阅读:
    [转]ubuntu的which、whereis、locate和find命令
    [转]理解SSL(https)中的对称加密与非对称加密
    SSL交互过程
    [转]程序开发基础学习二(C++ Google Style 命名规则)
    函数内动态分配内存
    sizeof和strlen
    Sublime Text 3 安装Package Control
    [转]使用Openssl的AES加密算法
    正则表达式
    论文书写常见问题与技巧
  • 原文地址:https://www.cnblogs.com/Dylan-Java-NYC/p/6475008.html
Copyright © 2011-2022 走看看