LRU Cache 解答

Question

Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: 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) - 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.

Solution

My first thought is to use a linked list and a hashmap. But remove and add element for linked list is O(n) per step.

So, the final idea is to implement a bi-directional linked list.

details

For this question, I submitted over 10 times and finally got accepted.

There are many details we need to check.

1. When deleting a node, we should modify both prev and next attributes of its neighbors.

2. Every time when we add a new node, we should check whether it is the first node.

3. When input capacity is 1, we should deal with it separately.

  1 // Construct double list node
  2 class Node {
  3     public Node prev;
  4     public Node next;
  5     private int val;
  6     private int key;
  7     public Node(int key, int val) {
  8         this.key = key;
  9         this.val = val;
 10     }
 11     public void setValue(int val) {
 12         this.val = val;
 13     }
 14     public int getKey() {
 15         return key;
 16     }
 17     public int getValue() {
 18         return val;
 19     }
 20 }
 21
 22
 23 public class LRUCache {
 24     private int capacity;
 25     private Map<Integer, Node> map;
 26     private Node head;
 27     private Node tail;
 28
 29     public LRUCache(int capacity) {
 30         this.capacity = capacity;
 31         map = new HashMap<Integer, Node>();
 32     }
 33
 34     private void moveToHead(Node target) {
 35         // Check whether target is already at head
 36         if (target.prev == null)
 37             return;
 38         // Check whether target is at tail
 39         if (target == tail)
 40             tail = target.prev;
 41         Node prev = target.prev;
 42         Node next = target.next;
 43         if (prev != null)
 44         prev.next = next;
 45         if (next != null)
 46             next.prev = prev;
 47
 48         Node oldHead = head;
 49         target.prev = null;
 50         target.next = oldHead;
 51         oldHead.prev = target;
 52         head = target;
 53     }
 54
 55     public int get(int key) {
 56         if (!map.containsKey(key))
 57             return -1;
 58         Node current = map.get(key);
 59         // Move found node to head
 60         moveToHead(current);
 61         return current.getValue();
 62     }
 63
 64     public void set(int key, int value) {
 65         if (map.containsKey(key)) {
 66             Node current = map.get(key);
 67             current.setValue(value);
 68             // Move found node to head
 69             moveToHead(current);
 70
 71         } else {
 72             Node current = new Node(key, value);
 73             // Add new node to map
 74             map.put(key, current);
 75
 76             // Check whether map size is bigger than capacity
 77             if (map.size() > capacity) {
 78                 // Move farest used element out
 79                 Node last = tail;
 80                 map.remove(last.getKey());
 81                 // Remove from list
 82                 if (map.size() == 1) {
 83                     head = current;
 84                     tail = current;
 85                 } else {
 86                     Node oldHead = head;
 87                     current.next = oldHead;
 88                     oldHead.prev = current;
 89                     head = current;
 90                     tail = tail.prev;
 91                     tail.next = null;
 92                 }
 93
 94             } else {
 95                 // Add new node to list
 96                 if (map.size() == 1) {
 97                     head = current;
 98                     tail = current;
 99                 } else {
100                     Node oldHead = head;
101                     current.next = oldHead;
102                     oldHead.prev = current;
103                     head = current;
104                 }
105             }
106         }
107     }
108 }
时间: 2024-10-06 00:20:45

LRU Cache 解答的相关文章

[LeetCode]LRU Cache有个问题,求大神解答

题目: Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: 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.

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

【Lintcode】LRU Cache, Data Stream Median

主要是priority_queue的用法 一个是内置类型优先队列怎么设置小根堆(默认大根堆) 如果是自定义数据结构,有两种办法 1.定义这种数据结构的比较符号,就可以当成内置类型整 2.传进去一个重载()的类,当小于号用,默认还是大根堆,也许传进去的是个callable object都行的吧,我试了一下函数好像不行,不懂,不管了 LRU Cache class LRUCache{ public: // @param capacity, an integer int Time; typedef i

LRU Cache的简单实现

Cache这个东西可以说无处不在,处理器中的TLB,Linux系统中的高速页缓存,还有很多人熟知的开源软件memcached,都是cache的一种实现.LRU是Least Recently Used的缩写,即最近最少使用,是常用cache算法中的一种.因为cache的存储空间相对于后端存储来说更有限,将cache空间和后端存储空间映射后,还需要一些算法来解决cache满的问题并保证效率,LRU就是在cache满了以后,将最近最少访问到的内容移除,然后将新的内容放入cache,新的内容也成为了最近

【LRU Cache】cpp

题目: Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: 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.

LRU Cache (9)

Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: 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

[leetcode]LRU Cache (python)

LRU:最近最久未使用,为了得到这个最新最久的信息,需要一种策略来进行记录,如果加入类似时间戳式的字段,那么每次删除的时候,就必须通过遍历才能得到时间信息,或者对时间戳进行排序,但是无论哪种,都是需要额外的维护,维护成本都比较高. 广泛使用的策略是底层用双端队列来进行维护,双端使得在插入删除时操作更简单.而单单使用双端队列似乎还是不够,比如在get 时,还是需要顺序查找给定的key参数的,所以为了能在O(1) 时间获得key 需要类hash的结构,在python里,就用字典. 接下来的事情是,我

LRU Cache

Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: 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(

LeetCode——LRU Cache

Description: Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and set. get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise r