[Swift]LeetCode460. LFU缓存 | LFU Cache (待完善)

Design and implement a data structure for Least Frequently Used (LFU)cache. It should support the following operations: get and 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

设计并实现最不经常使用(LFU)缓存的数据结构。它应该支持以下操作:get 和 put

get(key) - 如果键存在于缓存中,则获取键的值(总是正数),否则返回 -1。
put(key, value) - 如果键不存在,请设置或插入值。当缓存达到其容量时,它应该在插入新项目之前,使最不经常使用的项目无效。在此问题中,当存在平局(即两个或更多个键具有相同使用频率)时,最近最少使用的键将被去除。

进阶:
你是否可以在 O(1) 时间复杂度内执行两项操作?

示例:

LFUCache cache = new LFUCache( 2 /* capacity (缓存容量) */ );

cache.put(1, 1);
cache.put(2, 2);
cache.get(1);       // 返回 1
cache.put(3, 3);    // 去除 key 2
cache.get(2);       // 返回 -1 (未找到key 2)
cache.get(3);       // 返回 3
cache.put(4, 4);    // 去除 key 1
cache.get(1);       // 返回 -1 (未找到 key 1)
cache.get(3);       // 返回 3
cache.get(4);       // 返回 4

  1 class LFUCache {
  2     var head:Node? = nil
  3     var cap:Int = 0
  4     var valueHash:[Int:Int]
  5     var nodeHash:[Int:Node]
  6 
  7     init(_ capacity: Int) {
  8         self.cap = capacity
  9         self.valueHash = [Int:Int]()
 10         self.nodeHash = [Int:Node]()   
 11     }
 12     
 13     func get(_ key: Int) -> Int {
 14         if valueHash[key] != nil
 15         {
 16             increaseCount(key)
 17             return valueHash[key]!
 18         }
 19         return -1
 20     }
 21     
 22     func put(_ key: Int, _ value: Int) {
 23         if cap == 0 {return}
 24         if valueHash[key] != nil
 25         {
 26             valueHash[key] =  value
 27         }
 28         else
 29         {
 30             if valueHash.count < cap
 31             {
 32                 valueHash[key] =  value
 33             }
 34             else
 35             {
 36                 removeOld()
 37                 valueHash[key] =  value
 38             }
 39             addToHead(key)
 40         }
 41         increaseCount(key)      
 42     }
 43     
 44     private func addToHead(_ key:Int)
 45     {
 46         if head == nil
 47         {
 48             head = Node(0)
 49             head!.keys.insert(key)
 50         }
 51         else if head!.count > 0
 52         {
 53             var node:Node? = Node(0)
 54             node?.keys.insert(key)
 55             node?.next = head
 56             head?.prev = node
 57             head = node
 58         }
 59         else
 60         {
 61             head!.keys.insert(key)
 62         }
 63         nodeHash[key] = head
 64     }
 65     
 66     private func increaseCount(_ key:Int)
 67     {
 68         var node:Node? = nodeHash[key]
 69         node?.keys.remove(key)
 70         
 71         if node?.next == nil
 72         {
 73             node?.next = Node(node!.count+1)
 74             node?.next?.prev = node
 75             node?.next?.keys.insert(key)
 76         }
 77         else if node?.next!.count == node!.count+1
 78         {
 79             node?.next?.keys.insert(key)
 80         }
 81         else
 82         {
 83             var tmp:Node? = Node(node!.count+1)
 84             tmp?.keys.insert(key)
 85             tmp?.prev = node
 86             tmp?.next = node?.next
 87             node?.next?.prev = tmp
 88             node?.next = tmp
 89         }
 90         nodeHash[key] = node?.next
 91         if node?.keys.count == 0
 92         {
 93             remove(node)
 94         }
 95     }
 96     
 97     private func removeOld()
 98     {
 99         if head == nil {return}
100         var old:Int = 0
101         for n in head!.keys
102         {
103             old = n
104             break
105         }
106         head!.keys.remove(old)
107         if head!.keys.count == 0
108         {
109             remove(head)
110         }
111         nodeHash[old] = nil
112         valueHash[old] = nil
113     }
114     
115     private func remove(_ node:Node?)
116     {
117         if node?.prev ==  nil
118         {
119             head = node?.next
120         }
121         else
122         {
123             node!.prev?.next = node?.next
124         }
125         if node?.next != nil
126         {
127             node!.next?.prev = node?.prev
128         }        
129     }
130 }
131 
132 class Node {
133     var count: Int = 0
134     var keys:Set<Int>
135     var next: Node?
136     var prev: Node?
137 
138     init(_ count: Int) {
139         self.count = count
140         self.keys = Set<Int>()
141         self.next = nil
142         self.prev = nil
143     }
144 }
145 
146 /**
147  * Your LFUCache object will be instantiated and called as such:
148  * let obj = LFUCache(capacity)
149  * let ret_1: Int = obj.get(key)
150  * obj.put(key, value)
151  */
152  

 

相关文章

软件简介:蓝湖辅助工具,减少移动端开发中控件属性的复制和粘...
现实生活中,我们听到的声音都是时间连续的,我们称为这种信...
前言最近在B站上看到一个漂亮的仙女姐姐跳舞视频,循环看了亿...
【Android App】实战项目之仿抖音的短视频分享App(附源码和...
前言这一篇博客应该是我花时间最多的一次了,从2022年1月底至...
因为我既对接过session、cookie,也对接过JWT,今年因为工作...