11
11
12
12
巧妙点 :
13
13
1. head和tail特别巧妙 :除掉头和尾 ,和加上头和尾 ,就都特别快 。
14
- 2. 用双向的pointer : pre和next , 当需要除掉任何一个node的时候 ,只要知道要除掉哪一个 ,
14
+ 2. 用双向的pointer : pre和next , 当需要除掉任何一个node的时候 ,只要知道要除掉哪一个 ,
15
15
直接把node .pre和node .next耐心连起来就好了 ,node就自然而然的断开不要了 。
16
16
17
17
一旦知道怎么解决了 ,就不是很特别 ,并不是难写的算法 。
@@ -38,79 +38,96 @@ It looks like we need to do some design, according to (http://www.cnblogs.com/yu
38
38
Note:
39
39
Be careful: when removing a node due to capacity issue, remember to remove both 1st node(head.next) and the corresponding entry in the map: map.remove(head.next.key)
40
40
*/
41
- public class LRUCache {
42
- private class LinkNode {
43
- int key ;
44
- int val ;
45
- LinkNode pre = null ;
46
- LinkNode next = null ;
47
- LinkNode (int key , int val ) {
48
- this .key = key ;
49
- this .val = val ;
50
- }
51
- }
52
41
53
- private int cap ;
54
- private HashMap <Integer , LinkNode > map ;
55
- private LinkNode head ;
56
- private LinkNode tail ;
42
+ //Use double linked list to store value.
43
+ //Store key in hashmap<key, node> to find node easily
44
+ //Functions: insert in front, remove node,
45
+ public class LRUCache {
46
+ class DoubleLinkedListNode {
47
+ int key , val ;
48
+ DoubleLinkedListNode next ,prev ;
49
+ public DoubleLinkedListNode (int key , int val ){
50
+ this .key = key ;
51
+ this .val = val ;
52
+ next = null ;
53
+ prev = null ;
54
+ }
55
+ }
56
+ public int capacity ;
57
+ public HashMap <Integer , DoubleLinkedListNode > map ;
58
+ public DoubleLinkedListNode head , tail ;
57
59
public LRUCache (int capacity ) {
58
- this .cap = capacity ;
59
- this .map = new HashMap <Integer , LinkNode >();
60
- this .head = new LinkNode (-1 , -1 );
61
- this .tail = new LinkNode (-1 , -1 );
60
+ this .capacity = capacity ;
61
+ this .map = new HashMap <Integer , DoubleLinkedListNode >();
62
+ this .head = new DoubleLinkedListNode (-1 , -1 );
63
+ this .tail = new DoubleLinkedListNode (-1 , -1 );
62
64
head .next = tail ;
63
- tail .pre = head ;
65
+ head .prev = tail ;
66
+ tail .next = head ;
67
+ tail .prev = head ;
64
68
}
65
69
66
70
public int get (int key ) {
67
- if (map .containsKey (key )) {
68
- LinkNode temp = map .get (key );
69
- moveUsedToTail ( temp );
70
- return temp .val ;
71
- } else {
72
- return -1 ;
73
- }
71
+ if (map .containsKey (key )) {
72
+ DoubleLinkedListNode node = map .get (key );
73
+ moveToHead ( node );
74
+ return node .val ;
75
+ } else {
76
+ return -1 ;
77
+ }
74
78
}
75
79
76
80
public void set (int key , int value ) {
77
- if (map .containsKey (key )) {
78
- LinkNode temp = map .get (key );
79
- temp .val = value ;
80
- moveUsedToTail (temp );
81
- } else {
82
- if (map .size () >= cap ) {
83
- map .remove (head .next .key );
84
- removeHead ();
85
- }
86
- LinkNode newNode = new LinkNode (key , value );
87
- addTail (newNode );
88
- map .put (key , newNode );
89
- }
81
+ if (map .containsKey (key )) {
82
+ map .get (key ).val = value ;
83
+ moveToHead (map .get (key ));
84
+ } else {
85
+ DoubleLinkedListNode node = new DoubleLinkedListNode (key , value );
86
+ if (map .size () >= this .capacity ) {
87
+ DoubleLinkedListNode rm = tail .prev ;
88
+ remove (rm );
89
+ map .remove (rm .key );
90
+ }
91
+ insertHead (node );
92
+ map .put (key , node );
93
+ }
94
+ }
95
+
96
+ public void moveToTail (DoubleLinkedListNode node ) {
97
+ remove (node );
98
+ insertTail (node );
99
+ }
100
+
101
+ public void moveToHead (DoubleLinkedListNode node ) {
102
+ remove (node );
103
+ insertHead (node );
104
+ }
105
+
106
+ //Helper functions
107
+ public void insertHead (DoubleLinkedListNode node ) {
108
+ DoubleLinkedListNode next = head .next ;
109
+ head .next = node ;
110
+ node .prev = head ;
111
+ node .next = next ;
112
+ next .prev = node ;
113
+ }
114
+
115
+ public void insertTail (DoubleLinkedListNode node ) {
116
+ DoubleLinkedListNode prev = tail .prev ;
117
+ prev .next = node ;
118
+ node .prev = prev ;
119
+ node .next = tail ;
120
+ tail .prev = node ;
121
+ }
122
+
123
+ public void remove (DoubleLinkedListNode node ) {
124
+ DoubleLinkedListNode front = node .prev ;
125
+ DoubleLinkedListNode end = node .next ;
126
+ front .next = end ;
127
+ end .prev = front ;
90
128
}
91
129
92
- public void moveUsedToTail (LinkNode node ) {
93
- removeNode (node );
94
- addTail (node );
95
- }
96
-
97
- public void removeHead (){//O(1)
98
- removeNode (head .next );
99
- }
100
- public void addTail (LinkNode node ){//O(1)
101
- tail .pre .next = node ;
102
- node .pre = tail .pre ;
103
- node .next = tail ;
104
- tail .pre = node ;
105
- }
106
- public void removeNode (LinkNode node ) {//O(1)
107
- node .pre .next = node .next ;
108
- node .next .pre = node .pre ;
109
- }
110
130
}
111
-
112
- ````
113
- ````
114
131
/*
115
132
First Attempt: time exceeds
116
133
0 commit comments