1. Hash+双向链表

1.1 Java实现:

  1. public class LRUCache {
  2. class DLinkedNode {
  3. int key;
  4. int value;
  5. DLinkedNode pre;
  6. DLinkedNode next;
  7. DLinkedNode() {
  8. this.key = 0;
  9. this.value = 0;
  10. pre = null;
  11. next = null;
  12. }
  13. DLinkedNode(int key, int value) {
  14. this.key = key;
  15. this.value = value;
  16. pre = null;
  17. next = null;
  18. }
  19. }
  20. private ConcurrentMap<Integer, DLinkedNode> cache = new ConcurrentHashMap<Integer, DLinkedNode>();
  21. private int size;
  22. private int capacity;
  23. private DLinkedNode head, tail;
  24. public LRUCache(int capacity) {
  25. this.size = 0;
  26. this.capacity = capacity;
  27. head = new DLinkedNode();
  28. head.pre = null;
  29. tail = new DLinkedNode();
  30. tail.next = null;
  31. head.next = tail;
  32. tail.pre = head;
  33. }
  34. public int get(String key) {
  35. DLinkedNode node = cache.get(key);
  36. if (node == null) {
  37. return -1; // should raise exception here.
  38. }
  39. moveToHead(node);
  40. return node.value;
  41. }
  42. public void put(int key, int value) {
  43. if (cache.containsKey(key)) {
  44. DLinkedNode node = cache.get(key);
  45. node.value = value;
  46. moveToHead(node);
  47. } else {
  48. DLinkedNode node = new DLinkedNode(key, value);
  49. cache.put(key, node);
  50. addToHead(node);
  51. ++size;
  52. if (size > capacity) {
  53. DLinkedNode tail = removeTail();
  54. cache.remove(tail.key);
  55. size--;
  56. }
  57. }
  58. }
  59. private void moveToHead(DLinkedNode node) {
  60. removeNode(node);
  61. addToHead(node);
  62. }
  63. private void addToHead(DLinkedNode node) {
  64. node.pre = head;
  65. node.next = head.next;
  66. head.next.pre = node;
  67. head.next = node;
  68. }
  69. private void removeNode(DLinkedNode node) {
  70. DLinkedNode pre = node.pre;
  71. DLinkedNode next = node.next;
  72. pre.next = next;
  73. next.pre = pre;
  74. }
  75. private DLinkedNode removeTail() {
  76. DLinkedNode node = tail.pre;
  77. removeNode(node);
  78. return node;
  79. }
  80. }

1.2. C++实现

  1. struct DLinkedListNode {
  2. DLinkedListNode *next, *prev;
  3. int key, val;
  4. DLinkedListNode() : key(0), val(0), next(nullptr), prev(nullptr) {}
  5. DLinkedListNode(int key, int val) : key(key), val(val), next(nullptr), prev(nullptr) {}
  6. };
  7. class LRUCache {
  8. private:
  9. unordered_map<int, DLinkedListNode *> cache;
  10. DLinkedListNode *head, *tail;
  11. int size, capacity;
  12. public:
  13. LRUCache(int capacity) : capacity(capacity), size(0) {
  14. head = new DLinkedListNode();
  15. tail = new DLinkedListNode();
  16. head->next = tail;
  17. tail->prev = head;
  18. }
  19. int get(int key) {
  20. if (!cache.count(key)) {
  21. return -1;
  22. }
  23. DLinkedListNode *node = cache[key];
  24. moveToHead(node);
  25. return node->val;
  26. }
  27. void put(int key, int value) {
  28. if (!cache.count(key)) {
  29. DLinkedListNode *node = new DLinkedListNode(key, value);
  30. cache[key] = node;
  31. ++size;
  32. addToHead(node);
  33. if (size > capacity) {
  34. DLinkedListNode *node = removeTail();
  35. cache.erase(node->key);
  36. delete node;
  37. size -= 1;
  38. }
  39. } else {
  40. DLinkedListNode *node = cache[key];
  41. node->val = value;
  42. moveToHead(node);
  43. }
  44. }
  45. void moveToHead(DLinkedListNode *node) {
  46. removeNode(node);
  47. addToHead(node);
  48. }
  49. void removeNode(DLinkedListNode *node) {
  50. //1-->2-->3
  51. node->prev->next = node->next;
  52. node->next->prev = node->prev;
  53. }
  54. void addToHead(DLinkedListNode *node) {
  55. node->prev = head;
  56. node->next = head->next;
  57. // head->next->prev = node;
  58. node->next->prev = node;// try one time;
  59. head->next = node;
  60. }
  61. DLinkedListNode *removeTail() {
  62. DLinkedListNode *node = tail->prev;
  63. removeNode(node);
  64. return node;
  65. }
  66. };