题目链接:https://leetcode.com/problems/lru-cache/ 题目:
get
and set
.get(key)
- Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.
set(key, value)
思路:
用链表存储key的顺序关系,不管是用栈还是队列,在get元素和set已有元素时候,需要remove链表中的元素,如果用Java内置的链表,时间复杂度为O(n)。 会超时。
如果我们用HashMap保存每个key对应的链表结点的指针,那么remove的时候就可以根据key获取相应的指针,时间复杂度为O(1)。因为涉及到链表的删除,我们以前总结过,有头结点可以简化判断,又因为删除需要知道被删除结点的前后指针,所以用双向链表。又为了简化对尾结点删除的判断,加一个尾结点。
算法:
1. class Node {
2. Node pre, next;
3. int key, value;
4.
5. int key, int value, Node pre, Node next) {
6. this.key = key;
7. this.value = value;
8. this.pre = pre;
9. this.next = next;
10. }
11. }
12.
13. HashMap<Integer, Node> maps = new HashMap<Integer, Node>();
14. int capacity = 0;
15. Node head = null;
16. Node rear = null;
17.
18. public LRUCache(int capacity) {
19. this.capacity = capacity;
20. new Node(0, 0, null, null);
21. new Node(0, 0, null, null);
22. head.next = rear;
23. rear.pre = head;
24. }
25.
26. public int get(int key) {
27. if (maps.containsKey(key)) {
28. Node node = maps.get(key);
29. // remove node
30. node.pre.next = node.next;
31. node.next.pre = node.pre;
32. // put head
33. node.next = head.next;
34. head.next.pre = node;
35. head.next = node;
36. node.pre = head;
37. return node.value;
38. else {
39. return -1;
40. }
41. }
42.
43. public void set(int key, int value) {
44. if (maps.containsKey(key)) {
45. Node delete = maps.get(key);
46. // remove node
47. delete.pre.next = delete.next;
48. delete.next.pre = delete.pre;
49. else if (maps.size() == capacity) {
50. maps.remove(rear.pre.key);
51. // remove the last element
52. rear.pre.pre.next = rear;
53. rear.pre = rear.pre.pre;
54. null;
55. }
56. new Node(key, value, null, null);
57. // put head element
58. node.next = head.next;
59. head.next.pre = node;
60. head.next = node;
61. node.pre = head;
62. maps.put(key, node);
63. }