forked from JojoYang666/Leetcode-1-300
-
Notifications
You must be signed in to change notification settings - Fork 0
/
_146_LRUCache.java
134 lines (118 loc) · 3.88 KB
/
_146_LRUCache.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
package leetcode_1To300;
import java.util.HashMap;
/**
* 本代码来自 Cspiration,由 @Cspiration 提供
* 题目来源:http://leetcode.com
* - Cspiration 致力于在 CS 领域内帮助中国人找到工作,让更多海外国人受益
* - 现有课程:Leetcode Java 版本视频讲解(1-900题)(上)(中)(下)三部
* - 算法基础知识(上)(下)两部;题型技巧讲解(上)(下)两部
* - 节省刷题时间,效率提高2-3倍,初学者轻松一天10题,入门者轻松一天20题
* - 讲师:Edward Shi
* - 官方网站:https://cspiration.com
* - 版权所有,转发请注明出处
*/
public class _146_LRUCache {
/**
* 146. LRU Cache
* Design and implement a data structure for Least Recently Used (LRU) 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 reached its capacity,
it should invalidate the least recently used item before inserting a new item.
Follow up:
Could you do both operations in O(1) time complexity?
Example:
_146_LRUCache cache = new _146_LRUCache( 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.put(4, 4); // evicts key 1
cache.get(1); // returns -1 (not found)
cache.get(3); // returns 3
cache.get(4); // returns 4
HashMap + Double Linked List
插入:1,不存在 -> capacity -> 1,head = null 2,head != null
2,存在
取出:1,不存在
2,存在
=> 排序
time : O(1)
**/
class Node {
int key;
int value;
Node next;
Node pre;
public Node(int key, int value) {
this.key = key;
this.value = value;
}
}
private HashMap<Integer, Node> map;
private int capacity;
private Node head;
private Node tail;
public _146_LRUCache(int capacity) {
map = new HashMap<>();
this.capacity = capacity;
head = null;
tail = null;
}
public int get(int key) {
Node node = map.get(key);
if (node == null) {
return -1;
}
if (node != tail) {
if (node == head) {
head = head.next;
} else {
node.pre.next = node.next;
node.next.pre = node.pre;
}
tail.next = node;
node.pre = tail;
node.next = null;
tail = node;
}
return node.value;
}
public void put(int key, int value) {
Node node = map.get(key);
if (node != null) {
node.value = value;
if (node != tail) {
if (node == head) {
head = head.next;
} else {
node.pre.next = node.next;
node.next.pre = node.pre;
}
tail.next = node;
node.pre = tail;
node.next = null;
tail = node;
}
} else {
Node newNode = new Node(key, value);
if (capacity == 0) {
Node temp = head;
head = head.next;
map.remove(temp.key);
capacity++;
}
if (head == null && tail == null) {
head = newNode;
} else {
tail.next = newNode;
newNode.pre = tail;
newNode.next = null;
}
tail = newNode;
map.put(key, newNode);
capacity--;
}
}
}