每天写两道(二)LRU缓存、

146.LRU 缓存

. - 力扣(LeetCode)

请你设计并实现一个满足  LRU (最近最少使用) 缓存 约束的数据结构。

实现 LRUCache 类:

  • LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存
  • int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 。
  • void put(int key, int value) 如果关键字 key 已经存在,则变更其数据值 value ;如果不存在,则向缓存中插入该组 key-value 。如果插入操作导致关键字数量超过 capacity ,则应该 逐出 最久未使用的关键字。

函数 get 和 put 必须以 O(1) 的平均时间复杂度运行。 

思路:双向链表+一个哨兵节点,使用map记录(key,node)

(图和思路都是偷力扣大佬的) 

实现:

class Node {
    constructor(key, value) {
        this.key = key
        this.value = value
        this.pre = null
        this.next = null
    }
}

class LRUCache {
    constructor(capacity) {
        this.capacity = capacity
        this.dummy = new Node()
        this.dummy.next = this.dummy
        this.dummy.pre = this.dummy
        // 哈希表 用来存key和节点node
        this.keyToNodeMap = new Map()
    }
    // 删除x节点
    delete(x) {
        x.pre.next = x.next
        x.next.pre = x.pre
    }
    // 将节点添加在链表头 哨兵节点后
    addTop(x) {
        x.pre = this.dummy
        x.next = this.dummy.next
        x.pre.next = x
        x.next.pre = x
    }
    getNode(key) {
        // 没有该节点
        if (!this.keyToNodeMap.has(key)) { 
            return null;
        }
        // 有 拿出来放在头部
        const node = this.keyToNodeMap.get(key); 
        this.delete(node); 
        this.addTop(node); 
        return node;
    }
    get(key) {
        const node = this.getNode(key)
        return node?node.value:-1
    }
    put(key, value) {
        let node = this.getNode(key)
        // 有这个值 拿出来更新
        if (node) {
            node.value = value
        } else {
            // 新建节点放入
            node = new Node(key, value)
            this.keyToNodeMap.set(key, node)
            this.addTop(node)
            // 判断有没有溢出
            if (this.keyToNodeMap.size > this.capacity) {
                const backNode = this.dummy.pre
                this.keyToNodeMap.delete(backNode.key)
                this.delete(backNode)
            }
        }
    }
}

215.数组中最大的第k个元素

. - 力扣(LeetCode)

给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。

请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。

你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。 

思路:

看的是这位佬的:. - 力扣(LeetCode)

利用大根堆根节点最大的特性,构建大根堆,将根节点与最末尾节点交换,移出这个最大节点,再进行排序。。。

利用的是堆的思想,但实际是用数组来实现的 

顺序存储二叉树的特点:

第 n 个元素的 左子节点 为 2*n+1
第 n 个元素的 右子节点 为 2*n+2
第 n 个元素的 父节点 为 (n-1)/2
最后一个非叶子节点为 Math.floor(arr.length/2)-1

实现:

var findKthLargest = function (nums, k) {
    let len = nums.length
    // 先构建大根堆
    buildMaxHeap(nums, len)
    // 循环 将大根堆根节点和最末尾的节点交换
    // 循环到第k+1个最大就停止 最后返回的nums的根节点就是目标数
    // 这里for循环要用nums.length,不能用len,因为len是会改变的
    for (let i = nums.length - 1; i >= nums.length - k + 1; i--) {
        swap(nums, 0, i) // 将最大节点和最末尾的节点交换
        // 调整大根堆
        maxHeapify(nums, 0, --len) // 移到最后的节点不参与调整
    }
    return nums[0] // 返回第k个最大的值

    // 创建大根堆 自下而上构建大根堆
    function buildMaxHeap(nums, len) {
        // 最小非叶子节点:Math.floor(arr.length/2)-1
        for (let i = Math.floor(len / 2) - 1; i >= 0; i--) {
            maxHeapify(nums, i, len)
        }
    }
    function maxHeapify(nums, i, len) {
        let left = i * 2 + 1 // i的左子节点
        let right = i * 2 + 2 // i的右子节点
        let largest = i // 最大值的节点下标

        // 和左子节点比较
        if (left < len && nums[left] > nums[largest]) {
            largest = left
        }
        // 和右子节点比较
        if (right < len && nums[right] > nums[largest]) {
            largest = right
        }
        if (i !== largest) {
            swap(nums, i, largest) // 将子节点与父节点交换
            maxHeapify(nums, largest, len) // 再继续向下比较
        }
    }
    function swap(nums, a, b) {
        let temp = nums[a]
        nums[a] = nums[b]
        nums[b] = temp
    }

};

 今天写的两道都有点难,对于我这个白痴来说,所以明天还要再写一遍!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/657879.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

猜猜我是谁游戏

猜谜过程 在TabControl控件中&#xff0c;第一个tab中放了一个PictureBox&#xff0c;里面有一张黑色的图片。 玩家点击显示答案按钮&#xff0c;切换图片。 设计器 private void button1_Click(object sender, EventArgs e){this.pictureBox1.Image Image.FromFile(&qu…

网络渗透day2

Windows登录的明文密码存储过程和密文存储位置 明文密码存储过程&#xff1a; Windows操作系统不会以明文形式存储用户密码。相反&#xff0c;当用户设置或更改密码时&#xff0c;系统会对密码进行哈希处理&#xff0c;然后存储其哈希值。哈希处理的目的是为了提高密码的安全性…

设计模式——职责链(责任链)模式

目录 职责链模式 小俱求实习 结构图 实例 职责链模式优点 职责链模式缺点 使用场景 1.springmvc流程 ​2.mybatis的执行流程 3.spring的过滤器和拦截器 职责链模式 使多个对象都有机会处理请求&#xff0c;从而避免请求的发送者和接受者之间的耦合关系。将这个对象连成…

VM虚拟机共享文件夹fuse: bad mount point `/mnt/hgfs‘: No such file or directory

报错显示挂载点 /mnt/hgfs 不存在&#xff0c;你需要先创建这个目录。可以按照以下步骤进行操作&#xff1a; 创建挂载点目录&#xff1a; sudo mkdir -p /mnt/hgfs 手动挂载共享文件夹&#xff1a; sudo vmhgfs-fuse .host:/ /mnt/hgfs -o allow_other 确保每次启动时自动…

IDEA 2023.3.6 下载、安装、激活与使用

一、IDEA2023.3.6下载 国际官网&#xff1a;https://www.jetbrains.com/ 国内官网&#xff1a;https://www.jetbrains.com.cn/ 如果国际官网无法访问&#xff0c;就使用国内官网&#xff0c;我们以国内官网为例下载IDEA2023.3.6 首先进入首页如下图&#xf…

1.2数学基础

向量运算 矩阵运算 比较基础就不记录了 MVP矩阵推导 1.讲为什么要有矩阵变换和不同的坐标空间 将3D物体转化到2D平面为各个空间的运用做准备 2.介绍各个空间的概念和含义 MVP矩阵代表什么&#xff1f; MVP矩阵分别是模型(Model)、观察(View)、投影(Projection)三个矩阵。…

数组-捡石子小游戏

一、题目描述 二、解题思路 刚开始拿到题目的时候在想是不是需要把所有情况枚举出来&#xff0c;其实思考一下能看出规律&#xff1a; 1.如果有1、2、3颗石子&#xff0c;小牛一定可以赢&#xff1b; 2.再来看4颗石子的时候&#xff0c;小牛A可以拿1~3颗&#xff0c;但是无论小…

scrapy 整合 mitm

1.mitm 是什么 MITMproxy 是一个开源的中间人代理&#xff0c;常用于网络流量的拦截、查看和修改。 2.scrapy 整合 mitm步骤 2.1 安装mitm PS F:\studyScrapy\itcastScrapy> pip install mitmproxy2.2 在settings 中配置下载器中间件 # settings.pyDOWNLOADER_MIDDLEWARES…

工业路由器在新能源数字化中的应用:重塑能源行业的未来

随着全球对可再生能源和能源效率的追求日益加强&#xff0c;新能源数字化已成为推动行业发展的关键因素。在这一变革的浪潮中&#xff0c;工业路由器以其卓越的性能和独特的功能&#xff0c;成为新能源数字化不可或缺的核心组件。本文将深入探讨工业路由器在新能源数字化中的应…

如何解决链游中可能出现的延迟或网络拥堵问题?

随着区块链技术的不断发展和普及&#xff0c;链游&#xff08;基于区块链的游戏&#xff09;作为新兴的娱乐形式&#xff0c;正逐渐走进大众的视野。然而&#xff0c;与传统游戏相比&#xff0c;链游在运行过程中可能会遇到一些特有的问题&#xff0c;其中最为突出的就是延迟和…

YiShaAdmin:一款基于.NET Core Web + Bootstrap的企业级快速开发框架

前言 今天大姚给大家分享一款基于.NET Core Web Bootstrap的企业级快速后台开发框架、权限管理系统&#xff0c;代码简单易懂、界面简洁美观&#xff08;基于MIT License开源&#xff0c;免费可商用&#xff09;&#xff1a;YiShaAdmin。 项目官方介绍 YiShaAdmin 基于.NET…

孔子,孟子,荀子的以果决其行。

我们再往前&#xff0c;中间的有很多就不说了&#xff0c;我们可以自己去看他们的履历&#xff0c;看有没有——以果决其行的行为&#xff0c;以及有没有知行合一的身影。 再往前&#xff0c;到了孟子&#xff0c;孔孟都被称为圣人&#xff0c;孟子的很多话到现在我们都耳熟能详…

探索标准差与方差的奥秘

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、标准差与方差的基础理解 代码案例 二、标准差与方差的计算方法 方差的计算 标准差的…

STM32 入门教程(江科大教材)#笔记2

3-4按键控制LED /** LED.c**/ #include "stm32f10x.h" // Device headervoid LED_Init(void) {/*开启时钟*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //开启GPIOA的时钟/*GPIO初始化*/GPIO_InitTypeDef GPIO_InitStructure;GPIO_I…

少年应有鸿鹄志,当骑骏马踏平川!

点击上方蓝字关注狂神说 少年应有鸿鹄志&#xff0c;当骑骏马踏平川&#xff1a; 少年应当拥有鸿鹄一样的高远志向&#xff0c;翱翔长空&#xff0c;应当骑着骏马跨越山河平川。所谓少年&#xff0c;就应该意气风发&#xff0c;就应该胸怀壮志&#xff0c;追风赶月&#xff0c;…

Linux入门攻坚——23、DNS和BIND基础入门2

前一篇实践了正向解析服务器的配置使用&#xff0c;如何配置反向解析呢&#xff1f; 反向区域&#xff1a; 区域名称&#xff1a;网络地址反写.in-addr.arpa. 192.168.138. --> 138.168.192.in-addr.arpa. (1)定义区域&#xff1a; zone "ZONE_NAME" I…

CASS11自定义宗地图框

1、找到CASS11的安装路径&#xff0c;找到如下文件夹&#xff1a; 2、打开【report】文件夹&#xff0c;如下&#xff1a; 3、打开其中一个压缩包&#xff0c;如【标准宗地图】压缩包&#xff0c;结果如下&#xff1a; 4、打开后&#xff0c;将其另存为到桌面&#xff0c;随后关…

详解makefile中addprefix

在 Makefile 中&#xff0c;$(addprefix prefix,names…) 是一个函数&#xff0c;用于将指定的前缀添加到一组空格分隔的文件名中。这个函数通常用于将相同的前缀添加到一组文件名或路径中&#xff0c;非常适合在 Makefile 中进行路径拼接操作。 语法&#xff1a; makefile C…

ubuntu server 24.04 (Linux) 源码编译安装 OpenResty 1.25.3.1 Released

1 下载: OpenResty - 开源官方站 2 通过xftp等方式上传到ubuntu服务器 3 安装 #解压 tar zxvf openresty-1.25.3.1.tar.gz #创建运行用户 sudo groupadd www sudo useradd -g www www -s /bin/false #安装依赖软件 sudo apt update sudo apt-get install libpcre3-dev l…

如何创建一个vue项目?详细教程,如何创建第一个vue项目?

已经安装node.js在自己找的到的地方新建一个文件夹用于存放项目&#xff0c;记住文件夹的存放路径&#xff0c;以我为例&#xff0c;我的文件夹路径为D:\tydic 打开cmd命令窗口&#xff0c;进入刚刚的新建文件夹 切换硬盘&#xff1a; D: 进入文件夹&#xff1a;cd tydic 使…