Skip to content

Commit f19b397

Browse files
committed
Refactor solution to LRU Cache
1 parent af7f1f8 commit f19b397

File tree

1 file changed

+70
-54
lines changed

1 file changed

+70
-54
lines changed

Design/LRUCache.swift

+70-54
Original file line numberDiff line numberDiff line change
@@ -5,71 +5,87 @@
55
*
66
*/
77

8-
class DoublyLinkedList{
9-
var key: Int
10-
var value: Int
11-
var previous: DoublyLinkedList?
12-
var next: DoublyLinkedList?
13-
var hashValue: Int
8+
class LRUCache {
149

15-
init(_ key: Int, _ value: Int) {
16-
self.key = key
17-
self.value = value
18-
self.hashValue = key
19-
}
20-
}
10+
private let capacity: Int
11+
private let head = Node(0, 0)
12+
private let tail = Node(0, 0)
13+
14+
private var keyNodeMap = [Int: Node]()
2115

22-
class LRUCache{
23-
var maxCapacity: Int
24-
var head: DoublyLinkedList
25-
var tail: DoublyLinkedList
26-
var cache: [Int: DoublyLinkedList]
16+
init(_ capacity: Int) {
17+
self.capacity = capacity
18+
19+
head.next = tail
20+
tail.prev = head
21+
}
2722

28-
init(_ maxCapacity: Int) {
29-
self.maxCapacity = maxCapacity
30-
self.cache = [Int: DoublyLinkedList]()
31-
self.head = DoublyLinkedList(Int.min, Int.min)
32-
self.tail = DoublyLinkedList(Int.max, Int.max)
33-
self.head.next = self.tail
34-
self.tail.previous = self.head
23+
func get(_ key: Int) -> Int {
24+
guard let node = keyNodeMap[key] else {
25+
return -1
26+
}
27+
28+
remove(node)
29+
moveToHead(node)
30+
31+
return node.val
3532
}
3633

37-
func add(_ node: DoublyLinkedList){
38-
let next = head.next
39-
head.next = node
40-
node.previous = head
41-
node.next = next
42-
next?.previous = node
34+
func put(_ key: Int, _ value: Int) {
35+
let node = Node(key, value)
36+
37+
if let lastNode = keyNodeMap[key] {
38+
remove(lastNode)
39+
}
40+
41+
keyNodeMap[key] = node
42+
moveToHead(node)
43+
44+
if keyNodeMap.count > capacity {
45+
keyNodeMap[tail.prev!.key] = nil
46+
remove(tail.prev!)
47+
}
4348
}
4449

45-
func remove(_ node: DoublyLinkedList){
46-
let previous = node.previous
47-
let next = node.next
48-
previous?.next = next
49-
next?.previous = previous
50+
private func remove(_ node: Node) {
51+
let prev = node.prev
52+
let post = node.next
53+
54+
prev!.next = post
55+
post!.prev = prev
56+
57+
node.next = nil
58+
node.prev = nil
5059
}
5160

52-
func get(_ key: Int) -> Int{
53-
if let node = cache[key]{
54-
remove(node)
55-
add(node)
56-
return node.value
57-
}
58-
return -1
61+
private func moveToHead(_ node: Node) {
62+
let first = head.next
63+
64+
head.next = node
65+
66+
node.prev = head
67+
node.next = first
68+
69+
first!.prev = node
5970
}
6071

61-
func put(_ key: Int, _ value: Int){
62-
if let node = cache[key]{
63-
remove(node)
64-
cache.removeValue(forKey: key)
65-
}else if cache.keys.count >= maxCapacity{
66-
if let leastNode = tail.previous{
67-
remove(leastNode)
68-
cache.removeValue(forKey: leastNode.key)
69-
}
72+
class Node {
73+
let key: Int
74+
var val: Int
75+
76+
var prev: Node?
77+
var next: Node?
78+
79+
init(_ key: Int, _ val: Int) {
80+
self.key = key
81+
self.val = val
7082
}
71-
let newNode = DoublyLinkedList(key, value)
72-
cache[key] = newNode
73-
add(newNode)
7483
}
7584
}
85+
86+
/**
87+
* Your LRUCache object will be instantiated and called as such:
88+
* let obj = LRUCache(capacity)
89+
* let ret_1: Int = obj.get(key)
90+
* obj.put(key, value)
91+
*/

0 commit comments

Comments
 (0)