【设计】B001_用队列实现栈(双端队列 + Map / Map + 自定义双向链表 (代办))
程序员文章站
2022-06-12 22:50:46
...
一、Problem
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.
The cache is initialized with a positive capacity.
Follow up:
Could you do both operations in O(1) time complexity?
LRUCache cache = new 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
二、Solution
方法一:暴力做法
直接用 Map + LinkedList 做:
- put 时,检查 key 是否有对应的 v
- 如果有,则覆盖掉 Map 中的值,并且 q 的大小不能查过 cap,如果超了,pollFirst
- 否则,map 添加键值对
- get 时,也是先判空,此时的 key 为使用过,所以要变新。
删除操作耗费时间…
class LRUCache {
Map<Integer, Integer> mp;
ArrayDeque<Integer> q;
int cap;
public LRUCache(int capacity) {
mp = new HashMap<>(capacity);
q = new ArrayDeque<>();
cap = capacity;
}
public int get(int key) {
Integer v = mp.get(key);
if (v != null) {
q.remove(key);
q.add(key);
return v;
}
return -1;
}
public void put(int key, int value) {
Integer v = mp.get(key);
if (v != null) {
q.remove(key);
q.add(key);
} else if (q.size() < cap){
q.add(key);
} else {
int oldKey = q.pollFirst();
q.add(key);
mp.remove(oldKey);
}
mp.put(key, value);
}
}
复杂度分析
- 时间复杂度:,
- 空间复杂度:,
方法二:双向链表 + Map
- 定义一个 Node 内部类,存储 k、v、pre、next
- map 就存储 <K, Node> 类型的键值对,这样就可以通过 k 用 的时间找到 v,然后通过修改指针的指向来删除结点和添加结点。
复杂度分析
- 时间复杂度:,
- 空间复杂度:,
上一篇: Python3:函数