Skip to content

Commit f1d1f91

Browse files
committed
0146. LRU Cache
1 parent f409b16 commit f1d1f91

File tree

4 files changed

+396
-0
lines changed

4 files changed

+396
-0
lines changed

markdown/0146. LRU Cache.md

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
### [146\. LRU Cache](https://leetcode.com/problems/lru-cache/)
2+
3+
> 我使用双向循环链表和 hashtable 完成了,这里有一个小细节就是 put 的时候也是访问,需要将对应的 Node 提取到 head 上。
4+
5+
Difficulty: **Medium**
6+
7+
8+
Design and implement a data structure for . It should support the following operations: `get` and `put`.
9+
10+
`get(key)` - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.
11+
`put(key, value)` - Set or insert the value if the key is not already present. When the cache reached its capacity, it should invalidate the least recently used item before inserting a new item.
12+
13+
The cache is initialized with a **positive** capacity.
14+
15+
**Follow up:**
16+
Could you do both operations in **O(1)** time complexity?
17+
18+
**Example:**
19+
20+
```
21+
LRUCache cache = new LRUCache( 2 /* capacity */ );
22+
23+
cache.put(1, 1);
24+
cache.put(2, 2);
25+
cache.get(1); // returns 1
26+
cache.put(3, 3); // evicts key 2
27+
cache.get(2); // returns -1 (not found)
28+
cache.put(4, 4); // evicts key 1
29+
cache.get(1); // returns -1 (not found)
30+
cache.get(3); // returns 3
31+
cache.get(4); // returns 4
32+
```
33+
34+
35+
#### Solution
36+
37+
Language: **Java**
38+
39+
```java
40+
class LRUCache {
41+
42+
class LRUValue {
43+
int key;
44+
int value;
45+
LRUValue next; //链表下一个节点的key
46+
LRUValue pre;// 链表上一个节点的key
47+
48+
public LRUValue(int key, int value, LRUValue next, LRUValue pre) {
49+
this.key = key;
50+
this.value = value;
51+
this.next = next;
52+
this.pre = pre;
53+
}
54+
}
55+
56+
private Map<Integer, LRUValue> map = new HashMap<>();
57+
private int capacity;
58+
private LRUValue head;
59+
60+
public LRUCache(int capacity) {
61+
this.capacity = capacity;
62+
}
63+
64+
public int get(int key) {
65+
if (!map.containsKey(key)) {
66+
return -1;
67+
} else {
68+
LRUValue lruValue = map.get(key);
69+
if (lruValue != head) { // 如果获取的元素不是在头部,需要将该元素升级到头部
70+
promotionNode(lruValue);
71+
}
72+
return head.value;
73+
}
74+
}
75+
76+
public void put(int key, int value) {
77+
if (map.size() == 0) {
78+
LRUValue lruValue = new LRUValue(key, value, null, null);
79+
lruValue.next = lruValue;
80+
lruValue.pre = lruValue;
81+
head = lruValue;
82+
map.put(key, lruValue);
83+
} else {
84+
LRUValue targetValue = map.get(key);
85+
if (targetValue != null) {// 注意 put 也算是访问,需要把它提到 header
86+
if (targetValue != head) {
87+
promotionNode(targetValue);
88+
}
89+
targetValue.value = value;
90+
} else {
91+
if (map.size() >= capacity) {
92+
int removeKey = head.pre.key;
93+
head.pre = head.pre.pre;
94+
map.remove(removeKey);
95+
}
96+
LRUValue lruValue = new LRUValue(key, value, head, head.pre);
97+
map.put(key, lruValue);
98+
head.pre.next = lruValue;
99+
head.pre = lruValue;
100+
head = lruValue;
101+
}
102+
}
103+
}
104+
105+
private void promotionNode(LRUValue lruValue) {
106+
lruValue.pre.next = lruValue.next;
107+
lruValue.next.pre = lruValue.pre;
108+
head.pre.next = lruValue;
109+
lruValue.next = head;
110+
lruValue.pre = head.pre;
111+
head.pre = lruValue;
112+
head = lruValue;
113+
}
114+
}
115+
116+
/**
117+
* Your LRUCache object will be instantiated and called as such:
118+
* LRUCache obj = new LRUCache(capacity);
119+
* int param_1 = obj.get(key);
120+
* obj.put(key,value);
121+
*/
122+
```
123+
![](https://raw.githubusercontent.com/PicGoBed/PicBed/master/20190724010539.png)
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
package leetcode._146_;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
6+
/**
7+
* Created by zhangbo54 on 2019-07-23.
8+
*/
9+
class LRUCache {
10+
11+
class LRUValue {
12+
int key;
13+
int value;
14+
LRUValue next; //链表下一个节点的key
15+
LRUValue pre;// 链表上一个节点的key
16+
17+
public LRUValue(int key, int value, LRUValue next, LRUValue pre) {
18+
this.key = key;
19+
this.value = value;
20+
this.next = next;
21+
this.pre = pre;
22+
}
23+
}
24+
25+
private Map<Integer, LRUValue> map = new HashMap<>();
26+
private int capacity;
27+
private LRUValue head;
28+
29+
public LRUCache(int capacity) {
30+
this.capacity = capacity;
31+
}
32+
33+
public int get(int key) {
34+
if (!map.containsKey(key)) {
35+
return -1;
36+
} else {
37+
LRUValue lruValue = map.get(key);
38+
if (lruValue != head) { // 如果获取的元素不是在头部,需要将该元素升级到头部
39+
promotionNode(lruValue);
40+
}
41+
return head.value;
42+
}
43+
}
44+
45+
public void put(int key, int value) {
46+
if (map.size() == 0) {
47+
LRUValue lruValue = new LRUValue(key, value, null, null);
48+
lruValue.next = lruValue;
49+
lruValue.pre = lruValue;
50+
head = lruValue;
51+
map.put(key, lruValue);
52+
} else {
53+
LRUValue targetValue = map.get(key);
54+
if (targetValue != null) {// 注意 put 也算是访问,需要把它提到 header
55+
if (targetValue != head) {
56+
promotionNode(targetValue);
57+
}
58+
targetValue.value = value;
59+
} else {
60+
if (map.size() >= capacity) {
61+
int removeKey = head.pre.key;
62+
head.pre = head.pre.pre;
63+
map.remove(removeKey);
64+
}
65+
LRUValue lruValue = new LRUValue(key, value, head, head.pre);
66+
map.put(key, lruValue);
67+
head.pre.next = lruValue;
68+
head.pre = lruValue;
69+
head = lruValue;
70+
}
71+
}
72+
}
73+
74+
private void promotionNode(LRUValue lruValue) {
75+
lruValue.pre.next = lruValue.next;
76+
lruValue.next.pre = lruValue.pre;
77+
head.pre.next = lruValue;
78+
lruValue.next = head;
79+
lruValue.pre = head.pre;
80+
head.pre = lruValue;
81+
head = lruValue;
82+
}
83+
}
84+
85+
/**
86+
* Your LRUCache object will be instantiated and called as such:
87+
* LRUCache obj = new LRUCache(capacity);
88+
* int param_1 = obj.get(key);
89+
* obj.put(key,value);
90+
*/
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package leetcode._146_;
2+
3+
/**
4+
* Created by zhangbo54 on 2019-03-04.
5+
*/
6+
public class Main {
7+
public static void main(String[] args) {
8+
// LRUCache lruCache = new LRUCache(2);
9+
// lruCache.put(1, 1);
10+
// lruCache.put(2, 2);
11+
// System.out.println(lruCache.get(1));
12+
// lruCache.put(3, 3);
13+
// System.out.println(lruCache.get(2));
14+
// lruCache.put(4, 4);
15+
// System.out.println(lruCache.get(1));
16+
// System.out.println(lruCache.get(3));
17+
// System.out.println(lruCache.get(4));
18+
//
19+
//
20+
// System.out.println("------------");
21+
//
22+
// LRUCache lruCache2 = new LRUCache(2);
23+
// lruCache2.put(2, 1);
24+
// lruCache2.put(1, 1);
25+
// lruCache2.put(2, 3);
26+
// lruCache2.put(4, 1);
27+
// System.out.println(lruCache2.get(1));
28+
// System.out.println(lruCache2.get(2));
29+
//
30+
// System.out.println("------------");
31+
//
32+
// LRUCache lruCache3 = new LRUCache(2);
33+
// System.out.println(lruCache3.get(2));
34+
// lruCache3.put(2, 6);
35+
// System.out.println(lruCache3.get(1));
36+
// lruCache3.put(1, 5);
37+
// lruCache3.put(1, 2);
38+
// System.out.println(lruCache3.get(1));
39+
// System.out.println(lruCache3.get(2));
40+
//
41+
// System.out.println("------------");
42+
43+
LRUCache lruCache4 = new LRUCache(3);
44+
lruCache4.put(1, 1);
45+
lruCache4.put(2, 2);
46+
lruCache4.put(3, 3);
47+
lruCache4.put(4, 4);
48+
System.out.println(lruCache4.get(4));
49+
System.out.println(lruCache4.get(3));
50+
System.out.println(lruCache4.get(2));
51+
System.out.println(lruCache4.get(1));
52+
lruCache4.put(5, 5);
53+
System.out.println(lruCache4.get(1));
54+
System.out.println(lruCache4.get(2));
55+
System.out.println(lruCache4.get(3));
56+
System.out.println(lruCache4.get(4));
57+
System.out.println(lruCache4.get(5));
58+
}
59+
}
60+

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy