[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
[Swift]LeetCode460. LFU緩存 | LFU Cache (待完善)