每天写两道(二)LRU缓存、数组中最大的第k个元素

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/658979.html

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

相关文章

在Anki中按某个字段满足的条件查找笔记

Anki中可以使用deck、tag、card、note、is、prop、added、rated、nid、cid等关键字按照牌组、标签、卡片、卡片类型、状态、属性、添加时间、回答时间、对象id等对卡片进行筛选&#xff0c;但是没有提供按卡片字段进行筛选的关键字&#xff0c;那么&#xff0c;怎么按卡片字段是…

C++ (week5):Linux系统编程3:线程

文章目录 三、线程1.线程的基本概念①线程相关概念②我的理解 2.线程的基本操作 (API)(1)获取线程的标识&#xff1a;pthread_self(2)创建线程&#xff1a;pthread_create()(3)终止线程①pthread_exit()&#xff1a;当前线程终止&#xff0c;子线程主动退出②pthread_cancel()&…

安卓ADB通过WIFI无线连接手机[通过无线安装APK]

安卓ADB通过无线连接手机 本文摘录于&#xff1a;https://www.cnblogs.com/zhuxibo/p/14261117.html只是做学习备份之用&#xff0c;绝无抄袭之意&#xff0c;有疑惑请联系本人&#xff01; 别人给的操作确实可行,我这里实操记录如下: AdministratorpiaoranPC MINGW64 /e/Wor…

大模型部署框架 FastLLM 简要解析

0x0. 前言 本文主要是对FastLLM做了一个简要介绍&#xff0c;展示了一下FastLLM的部署效果。然后以chatglm-6b为例&#xff0c;对FastLLM模型导出的流程进行了解析&#xff0c;接着解析了chatglm-6b模型部分的核心实现。最后还对FastLLM涉及到的优化技巧进行了简单的介绍。 0…

Java 阻塞队列与生产者消费者模型

一、阻塞队列 阻塞队列是⼀种特殊的队列&#xff0c;其也遵守队列 "先进先出" 的原则&#xff1b; 阻塞队列是⼀种线程安全的数据结构&#xff0c;并且具有以下特性&#xff1a; 当队列满的时候&#xff0c;继续入队列就会阻塞&#xff0c;直到有其他线程从队列中…

成都市酷客焕学新媒体科技有限公司:助力品牌打破困境!

在数字化浪潮的推动下&#xff0c;营销策略对品牌的发展愈发关键。成都市酷客焕学新媒体科技有限公司&#xff0c;作为短视频营销领域的佼佼者&#xff0c;凭借其卓越的策略和实力&#xff0c;助力众多品牌在信息海洋中脱颖而出&#xff0c;实现品牌的显著增长。 酷客焕学专注于…

抖音和快手哪个好?来全面了解一下他们的区别!

快手和抖音虽然是短视频领域的两大主流平台&#xff0c;但是两者也存在本质的区别&#xff0c;从产品定位、用户群体到视频风格、变现模式&#xff0c;它们的特征都不一样。 &#xff08;一&#xff09;两个平台核心区别&#xff1a; 1. 核心用户不一样&#xff1a;抖音以1、…

【最优化方法】实验四 约束最优化方法的MATLAB实现

实验的目的和要求&#xff1a;通过本次实验使学生较为熟练使用MATLAB软件&#xff0c;并能利用该软件进行约束最优化方法的计算。 实验内容&#xff1a; &#xff11;、罚函数法的MATLAB实现 &#xff12;、可行方向法的MATLAB实现 学习建议&#xff1a; 本次实验就是要通…

942. 增减字符串匹配 - 力扣

1. 题目 由范围 [0,n] 内所有整数组成的 n 1 个整数的排列序列可以表示为长度为 n 的字符串 s &#xff0c;其中: 如果 perm[i] < perm[i 1] &#xff0c;那么 s[i] I 如果 perm[i] > perm[i 1] &#xff0c;那么 s[i] D 给定一个字符串 s &#xff0c;重构排列 pe…

新能源汽车推行精益生产:绿色动力下的效率革命

在新能源汽车行业迅猛发展的当下&#xff0c;推行精益生产已成为提升竞争力的关键所在。精益生产&#xff0c;作为一种以客户需求为导向、追求流程最优化和浪费最小化的管理理念&#xff0c;正逐步在新能源汽车领域展现出其独特的魅力。 新能源汽车的兴起&#xff0c;不仅代表了…

【云原生】kubernetes中Configmap原理解析与应用实战

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

Python中tkinter入门编程9

在《Python中tkinter编程入门8-CSDN博客》中提到&#xff0c;tkinter中的Canvas表示画布&#xff0c;可以在画布中显示文字和图片。除了以上功能外&#xff0c;还可以在Canvas中添加对鼠标或键盘的响应。 1 为Canvas添加事件响应 可以通过Canvas的bind()方法添加对鼠标或键盘…

深圳比创达电子|EMC与EMI滤波器:电子设备的“电磁防护罩”

在电子科技日新月异的今天&#xff0c;电磁兼容性&#xff08;EMC&#xff09;问题越来越受到工程师和技术人员的关注。其中&#xff0c;电磁干扰&#xff08;EMI&#xff09;和电磁干扰抑制&#xff08;即EMI滤波器&#xff09;是实现良好EMC性能的关键技术之一。 一、EMC与E…

1218. 最长定差子序列

1218. 最长定差子序列 原题链接&#xff1a;完成情况&#xff1a;解题思路&#xff1a;参考代码&#xff1a;_1218最长定差子序列 错误经验吸取 原题链接&#xff1a; 1218. 最长定差子序列 https://leetcode.cn/problems/longest-arithmetic-subsequence-of-given-differen…

FlashRAG

文章目录 一、关于 FlashRAG特点 ✨&#x1f527; 安装 二、快速入门&#x1f3c3;1、Toy Example2、使用现成的管道3、建立自己的管道4、只需使用组件 三、组件⚙️1、RAG 组件2、管道 四、支持方法&#x1f916;五、支持数据集&#x1f4d3;六、其他常见问题解答 &#x1f64…

MT3049 区间按位与

思路&#xff1a; 使用ST表。ST表模板可参考MT3024 maxmin 注意点&#xff1a;此题范围较大&#xff0c;所以要避免超时。 ①使用 ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); 加快输入输出速度。 ②换行使用\n而不是endl 代码&#xff1a; 1.暴力6/8 #…

图片怎么批量重命名从1到50?这3个方法一键改名

图片怎么批量重命名从1到50&#xff1f;图片批量重命名从1到50的过程不仅提高了我们处理大量图片文件的效率&#xff0c;还大大简化了命名过程&#xff0c;让我们能更加有条理地管理和存储图片。通过使用各种专业的工具和方法&#xff0c;我们可以轻松实现图片文件的自动化命名…

微信小程序代码加固教程后台接口防止别人乱调用

最近开发了一个小程序前端开发前端和后台花了1个多月时间开发&#xff0c;结果被人轻松的把微信小程序前端代码破解出来。而且完整一个字不差截图给我看了。 小程序是前后端都分离的&#xff0c;如果后端不作验证&#xff0c;别人把你的小程序前端扒了接口也暴露了&#xff0c;…

玩转STM32-通用同步/异步收发器USART(详细-慢工出细活)

CPU与外围设备之间的信息交换或计算机与计算机之间的信息交换称为通信。基 本的通信方式有两种&#xff0c;即并行通信和串行通信。文章目录 一、串行通信基础1.1 串行通信的方式1.2 串行通信的数据传输形式1.3 波特率 二、STM32的USART的结构特征&#xff08;了解&#xff09;…

现在怎么做抖店才能赚钱?这四个重要建议,你千万不能忽略!

大家好&#xff0c;我是电商花花。 现在目前看抖音小店前景和红利依然有很大的市场空间&#xff0c;抖音小店平台流量大&#xff0c;商家入驻门槛低&#xff0c;抖店的运营技术也不像其它传统电商平台那么高。 所以&#xff0c;当下抖音小店仍然是流量大&#xff0c;机遇多。…