-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLeetCode0146.java
145 lines (128 loc) · 4.06 KB
/
LeetCode0146.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/* LRU Cache
* Input:
* ["LRUCache", "put", "put", "get", "put", "get", "put", "get", "get", "get"]
* [[2], [1, 1], [2, 2], [1], [3, 3], [2], [4, 4], [1], [3], [4]]
* Output:
* [null, null, null, 1, null, -1, null, -1, 3, 4]
* */
import java.util.LinkedHashMap;
public class LeetCode0146 {
public static void main(String args[]) {
LRUCache LRUcache = new LRUCache(2);
LRUcache.put(1, 1);
LRUcache.put(2, 2);
System.out.println(LRUcache.get(1));
LRUcache.put(3, 3);
System.out.println(LRUcache.get(2));
LRUcache.put(4, 4);
System.out.println(LRUcache.get(1));
System.out.println(LRUcache.get(3));
System.out.println(LRUcache.get(4));
}
}
class LRUCache {
LinkedHashMap<Integer, Integer> cache = new LinkedHashMap<>();
int cap;
public LRUCache(int capacity) {
this.cap = capacity;
}
public int get(int key) {
if (!cache.containsKey(key))
return -1;
move(key);
return cache.get(key);
}
public void put(int key, int value) {
if (cache.containsKey(key)){
cache.put(key, value);
move(key);
return;
}
if (cache.size() >= cap){
//System.out.println(cache.keySet());
int oldest = cache.keySet().iterator().next();
cache.remove(oldest);
}
cache.put(key, value);
}
public void move(int key){
int val = cache.get(key);
cache.remove(key);
cache.put(key, val);
}
/* 不用LinkedHashMap,结合HashMap和双向列表(此方法更快)
class DLinkedNode {
int key;
int value;
DLinkedNode prev;
DLinkedNode next;
public DLinkedNode() {}
public DLinkedNode(int _key, int _value) {key = _key; value = _value;}
}
private Map<Integer, DLinkedNode> cache = new HashMap<Integer, DLinkedNode>();
private int size;
private int capacity;
private DLinkedNode head, tail;
public LRUCache(int capacity) {
this.size = 0;
this.capacity = capacity;
// 使用伪头部和伪尾部节点
head = new DLinkedNode();
tail = new DLinkedNode();
head.next = tail;
tail.prev = head;
}
public int get(int key) {
DLinkedNode node = cache.get(key);
if (node == null) {
return -1;
}
// 如果 key 存在,先通过哈希表定位,再移到头部
moveToHead(node);
return node.value;
}
public void put(int key, int value) {
DLinkedNode node = cache.get(key);
if (node == null) {
// 如果 key 不存在,创建一个新的节点
DLinkedNode newNode = new DLinkedNode(key, value);
// 添加进哈希表
cache.put(key, newNode);
// 添加至双向链表的头部
addToHead(newNode);
++size;
if (size > capacity) {
// 如果超出容量,删除双向链表的尾部节点
DLinkedNode tail = removeTail();
// 删除哈希表中对应的项
cache.remove(tail.key);
--size;
}
}
else {
// 如果 key 存在,先通过哈希表定位,再修改 value,并移到头部
node.value = value;
moveToHead(node);
}
}
private void addToHead(DLinkedNode node) {
node.prev = head;
node.next = head.next;
head.next.prev = node;
head.next = node;
}
private void removeNode(DLinkedNode node) {
node.prev.next = node.next;
node.next.prev = node.prev;
}
private void moveToHead(DLinkedNode node) {
removeNode(node);
addToHead(node);
}
private DLinkedNode removeTail() {
DLinkedNode res = tail.prev;
removeNode(res);
return res;
}
*/
}