【科学刷题】数据结构的综合应用

716. 最大栈

双端队列 + 平衡树

LRU,LFU,数据流中位数

研究一下字节面试题

381. O(1) 时间插入、删除和获取随机元素 - 允许重复

这题还有配套的

146. LRU 缓存机制

146. LRU 缓存机制

牛客 - [编程题]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]));
            }
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值