|
1 | 1 | class LRUCache {
|
2 |
| - private static class DLLNode { |
| 2 | + private class DLLNode { |
| 3 | + private int key, value; |
3 | 4 | private DLLNode next, prev;
|
4 |
| - private int key; |
5 |
| - private int value; |
6 | 5 |
|
7 |
| - public DLLNode(int key, int value) { |
8 |
| - this.key = key; |
9 |
| - this.value = value; |
| 6 | + public DLLNode() { |
| 7 | + key = -1; |
| 8 | + value = -1; |
| 9 | + |
| 10 | + next = null; |
| 11 | + prev = null; |
| 12 | + } |
| 13 | + |
| 14 | + public DLLNode(int k, int v) { |
| 15 | + key = k; |
| 16 | + value = v; |
| 17 | + |
| 18 | + next = null; |
| 19 | + prev = null; |
10 | 20 | }
|
11 | 21 | }
|
12 | 22 |
|
13 |
| - private int capacity; |
14 | 23 | private DLLNode head, tail;
|
15 | 24 | private Map<Integer, DLLNode> hm;
|
| 25 | + private int cap, size; |
16 | 26 |
|
17 | 27 | public LRUCache(int capacity) {
|
18 |
| - this.capacity = capacity; |
| 28 | + cap = capacity; |
| 29 | + size = 0; |
| 30 | + |
19 | 31 | hm = new HashMap<>();
|
20 | 32 |
|
21 |
| - head = tail = new DLLNode(-1, -1); |
| 33 | + head = new DLLNode(); |
| 34 | + tail = new DLLNode(); |
| 35 | + |
22 | 36 | head.next = tail;
|
23 | 37 | tail.prev = head;
|
24 | 38 | }
|
25 | 39 |
|
26 | 40 | public int get(int key) {
|
27 |
| - DLLNode node = hm.get(key); |
28 |
| - if (node == null) { |
| 41 | + if (!hm.containsKey(key)) { |
29 | 42 | return -1;
|
30 | 43 | }
|
31 | 44 |
|
32 |
| - moveNodeToHead(node); |
| 45 | + DLLNode node = hm.get(key); |
| 46 | + moveToHead(node); |
33 | 47 | return node.value;
|
34 | 48 | }
|
35 | 49 |
|
36 | 50 | public void put(int key, int value) {
|
37 |
| - DLLNode node = hm.get(key); |
38 |
| - |
39 |
| - if (node != null) { |
| 51 | + if (hm.containsKey(key)) { |
| 52 | + DLLNode node = hm.get(key); |
40 | 53 | node.value = value;
|
41 |
| - moveNodeToHead(node); |
| 54 | + hm.put(key, node); |
| 55 | + moveToHead(node); |
42 | 56 | return;
|
43 | 57 | }
|
44 | 58 |
|
45 |
| - node = new DLLNode(key, value); |
| 59 | + DLLNode node = new DLLNode(key, value); |
46 | 60 | hm.put(key, node);
|
47 |
| - addNode(node); |
| 61 | + moveToHead(node); |
| 62 | + ++size; |
48 | 63 |
|
49 |
| - if (hm.size() > capacity) { |
50 |
| - hm.remove(tail.prev.key); |
51 |
| - removeTail(tail.prev); |
| 64 | + if (size > cap) { |
| 65 | + remove(tail.prev); |
| 66 | + --size; |
52 | 67 | }
|
53 | 68 | }
|
54 | 69 |
|
55 |
| - private void moveNodeToHead(DLLNode node) { |
56 |
| - removeNode(node); |
57 |
| - addNode(node); |
58 |
| - } |
| 70 | + private void remove(DLLNode node) { |
| 71 | + node.prev.next = node.next; |
| 72 | + node.next.prev = node.prev; |
59 | 73 |
|
60 |
| - private void removeTail(DLLNode node) { |
61 |
| - removeNode(node); |
| 74 | + hm.remove(node.key); |
62 | 75 | }
|
63 | 76 |
|
64 |
| - private void addNode(DLLNode node) { |
| 77 | + private void moveToHead(DLLNode node) { |
| 78 | + if (node.prev != null) { |
| 79 | + node.prev.next = node.next; |
| 80 | + } |
| 81 | + |
| 82 | + if (node.next != null) { |
| 83 | + node.next.prev = node.prev; |
| 84 | + } |
| 85 | + |
65 | 86 | node.next = head.next;
|
66 | 87 | node.prev = head;
|
67 | 88 |
|
68 | 89 | head.next.prev = node;
|
69 | 90 | head.next = node;
|
70 | 91 | }
|
71 |
| - |
72 |
| - private void removeNode(DLLNode node) { |
73 |
| - if (node == null) { |
74 |
| - return; |
75 |
| - } |
76 |
| - |
77 |
| - DLLNode prev = node.prev; |
78 |
| - DLLNode next = node.next; |
79 |
| - |
80 |
| - prev.next = next; |
81 |
| - next.prev = prev; |
82 |
| - } |
83 | 92 | }
|
0 commit comments