双端队列 + 平衡树
LRU,LFU,数据流中位数
研究一下字节面试题
381. O(1) 时间插入、删除和获取随机元素 - 允许重复
这题还有配套的
146. LRU 缓存机制看了一下以前的代码,迷迷糊糊默写的,居然过了,离谱。。
双向链表:
- addLast : 队尾入队
- remove:删除一个结点
- removeFirst:队首出队
LRUCache:
- makeRecently:将元素拿到队尾
- removeLeastRecently:删除对少最近,其实就是删队头
- addRecently: 入队
- removeKey: 删除任意一个结点
class Node():
def __init__(self, k, v):
self.k = k
self.v = v
self.prev = None
self.next = None
class DoubleList():
def __init__(self):
self.head = Node(0, 0)
self.tail = Node(0, 0)
self.head.next = self.tail
self.tail.prev = self.head
self.size = 0
def addLast(self, x: Node):
x.next = self.tail
x.prev = self.tail.prev
self.tail.prev.next = x
self.tail.prev = x
self.size += 1
def remove(self, x):
x.prev.next = x.next
x.next.prev = x.prev
self.size -= 1
def removeFirst(self):
if self.head.next == self.tail:
return None
first = self.head.next
self.remove(first)
return first
class LRUCache:
def __init__(self, capacity: int):
self.capacity = capacity
self.cache = DoubleList()
self.map: Dict[int, Node] = {}
def get(self, key: int) -> int:
if key in self.map:
self.makeRecently(key)
return self.map[key].v
return -1
def put(self, key: int, value: int) -> None:
if key not in self.map:
if self.cache.size == self.capacity:
self.removeLeastRecently()
self.addRecently(key, value)
self.removeKey(key)
self.addRecently(key, value)
def makeRecently(self, key):
node = self.map[key]
self.cache.remove(node)
self.cache.addLast(node)
def removeLeastRecently(self):
first = self.cache.removeFirst()
self.map.pop(first.k)
def addRecently(self, key, value):
node = Node(key, value)
self.map[key] = node
self.cache.addLast(node)
如果用Java的LinkedHashSet
来刷的话,会很方便,不过需要记住删队头结点的代码是取KeySet
然后迭代得到第一个key最后remove掉
import java.util.LinkedHashMap;
import java.util.Scanner;
class LRU {
int capacity;
LinkedHashMap<Integer, Integer> cache;
LRU(int capacity) {
this.capacity = capacity;
cache = new LinkedHashMap<>();
}
int makeRecently(int k) {
int v = cache.get(k);
cache.remove(k);
cache.put(k, v);
return v;
}
void addRecently(int k, int v) {
cache.put(k, v);
}
void removeKey(int k) {
cache.remove(k);
}
void removeLeastRecently() {
int oldestKey = cache.keySet().iterator().next();
cache.remove(oldestKey);
}
void put(int k, int v) {
if (cache.containsKey(k)) {
removeKey(k);
addRecently(k, v);
} else {
if (cache.size() >= capacity) {
removeLeastRecently();
}
addRecently(k, v);
}
}
int get(int k) {
if (cache.containsKey(k))
return makeRecently(k);
return -1;
}
}
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int n = input.nextInt();
int capacity = input.nextInt();
input.nextLine();
LRU lru = new LRU(capacity);
for (int i = 0; i < n; i++) {
String[] line = input.nextLine().split(" ");
if (line[0].equals("GET")) System.out.println(lru.get(Integer.valueOf(line[1])));
if (line[0].equals("PUT")) lru.put(Integer.valueOf(line[1]), Integer.valueOf(line[2]));
}
}
}
import java.util.*;
class LRU{
int capacity;
LinkedHashMap<Integer,Integer> cache;
LRU(int capacity){
this.capacity=capacity;
cache=new LinkedHashMap<Integer,Integer>();
}
void put(int k, int v){
if(cache.containsKey(k)){
cache.remove(k);
cache.put(k,v);
}else{
if(cache.size()>=capacity){
int oldK=cache.keySet().iterator().next();
cache.remove(oldK);
}
cache.put(k, v);
}
}
int get(int k){
if(cache.containsKey(k)){
int v=cache.get(k);
cache.remove(k);
cache.put(k,v);
return v;
}
return -1;
}
}
public class Main{
public static void main(String[] args){
Scanner input = new Scanner(System.in);
int n=input.nextInt();
int capacity=input.nextInt();
input.nextLine();
LRU lru=new LRU(capacity);
while(n-->0){
String [] line=input.nextLine().split(" ");
if(line.length==2){
System.out.println(lru.get(Integer.parseInt(line[1])));
}else{
lru.put(Integer.parseInt(line[1]), Integer.parseInt(line[2]));
}
}
}
}