java数据结构与算法刷题-----LeetCode215. 数组中的第K个最大元素

news2024/11/14 8:49:28
java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完):https://blog.csdn.net/grd_java/article/details/123063846

文章目录

在这里插入图片描述

解题思路:时间复杂度O( n n n),空间复杂度O( l o g 2 n log_2{n} log2n)
  1. 使用小根堆,建堆时间复杂度O(k),调整堆(删除堆顶并插入新元素)O( n ∗ l o g 2 k n*log_2k nlog2k),其中k是题目要求的返回第k最大元素。因此小根堆大小为k,故建堆为O(k). 共计O( k + n ∗ l o g 2 k k+n*log_2k k+nlog2k) = O(n)
  2. 不断地将元素插入到小根堆(根最小,其它元素都比根大)中,当堆中有k个元素,此时还需要往堆中插入元素时,需要进行判断。
  3. 因为此时堆顶元素正好是堆中倒数第k大元素。如果新插入元素比堆顶大。证明当前堆顶不是倒数第k大
  4. 则堆顶删除,并将新元素插入。此时调整堆,新的堆顶元素为第k大。以此类推。直到所有元素入堆后。
  5. 最终返回堆顶即可。
堆排序https://blog.csdn.net/grd_java/article/details/136937525
代码:当前官方增加了很多测试用例,已经无法超越100%的用户了,目前最快的算法,只能达到17ms,进行优化后,也只到了15ms。我查看2021年提交时的记录,是3ms超越100%。目前已经无法达到了。
  1. 使用Java提供的优先级队列实现小根堆(面试时候肯定不让你用。因此这个代码帮你理解整体的思路。然后第二个实现方法,我们需要自己实现小根堆)
    在这里插入图片描述
class Solution {
    //[6,5]
    //
    public int findKthLargest(int[] nums, int k) {
        PriorityQueue<Integer> queue = new PriorityQueue<>(new Comparator<Integer>() {
            //返回值>0,o1放在o2后面。反之o1放o2前面
            //小根堆,小的在前面。利用o1-o2实现。如果o1小,o1-o2<0,o1会放在o2前面
            //如果o1大o2小,o1-o2>0,o1会放在o2后面。而小的o2放在o1前面
            @Override
            public int compare(Integer o1, Integer o2) {
                return o1 - o2;
            }
        });
        for(int num:nums){
            if(queue.size() == k){
                if(queue.peek() < num) {
                    queue.poll();
                    queue.offer(num);
                }
            }else{
                queue.offer(num);
            }
        }
        return queue.poll();
    }
}
  1. 自己实现小根堆,因为Java自带容器加了很多健壮性和线程安全的逻辑,所以效率较慢,我们自己实现小根堆就会快很多。
    在这里插入图片描述
class Solution {
        public int findKthLargest(int[] nums, int k) {
        int[] minHeap = new int[k];//小根堆
        for (int i = 0; i < k; i++) {//大小为k
            minHeap[i] = nums[i];
        }
        //k/2-1是二叉树的知识,代表以k个结点构成的二叉树的第一个非叶子结点。k/2-2是第二个非叶子,以此类推。i == 0是整个二叉树的根结点
        for (int i = k / 2 - 1; i >= 0; i--) {//调整小根堆,从下到上,依次让每一颗子树满足小根堆
            adjustHeap(minHeap, i);//i是二叉树的每个非叶子结点,小根堆的要求是:每个子树,根结点都是整棵树最小
        }
        //小根堆构建完成后,minHeap[0]就是当前第k大的数。接下来需要不断进行判断和入堆操作
        for (int i = k; i < nums.length; i++) {
            if (nums[i] > minHeap[0]) {//如果当前i,是比小根堆堆顶更大的元素,那么堆顶不是第k大,
                minHeap[0] = nums[i];//将堆顶出堆,并将i放在堆顶位置
                adjustHeap(minHeap, 0);//此时很有可能小根堆逻辑被破坏,也就是i太大,不满足小根堆,因此需要让i进行下降调整,让其重新满足小根堆定义
            }
        }
        return minHeap[0];
    }

    /**
     * 以root为根结点构建/调整堆
     * @param array 堆
     * @param root 当前根结点
     */
    private void adjustHeap(int[] array, int root) {
        //让root结点下降到合适位置,以满足小根堆效果(任何一颗子树,根结点都是最小的)
        while (true) {//当堆调整完成后,结束
            int left = 2 * root + 1;//获得root的左子结点下标
            int right = left + 1;//获得root的右子结点下标
            int min = root;//最小值,最终需要放到root结点位置
            //如果左子结点存在,并且左子结点更小,让min指向这个结点
            if (left < array.length && array[left] < array[min]) min = left;
            //如果右子结点存在,并且右子结点更小,让min指向这个结点
            if (right < array.length && array[right] < array[min]) min = right;
            //如果min == root说明小根堆调整结束
            if (min == root) break;
            //让min当前指向位置和root交换,也就是下降操作,说明root当前指向的结点不是最小值,不满足小根堆
            //因为小根堆,越上面层次的结点,越小,所以如果当前root太大,需要让其下降
            swap(array, root, min);
            //root本次下降完成后,min的位置是root新的位置。因为root下降到min的位置
            //让root指向min,然后继续循环,判断是否root需要继续下降。直到它下降到合适位置
            root = min;
        }
    }

    private void swap(int[] array, int i, int j) {
        int temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

大屏可视化综合展示解决方案

1.系统概述 1.1.需求分析 1.2.重难点分析 1.3.重难点解决措施 2.系统架构设计 2.1.系统架构图 2.2.关键技术 2.3.接口及要求 3.系统功能设计 3.1.功能清单列表 3.2.数据源管理 3.3.数据集管理 3.4.视图管理 3.5.仪表盘管理 3.6.移动端设计 3.1.系统权限设计 3.…

STM32 CAN的位时序和波特率

STM32 CAN的位时序和波特率 位时序 STM32的CAN外设位时序中只包含3段&#xff0c;分别是同步段SYNC_SEG、位段BS1及位段BS2&#xff0c;采样点位于BS1及BS2段的交界处。其中SYNC_SEG段固定长度为1Tq&#xff0c;而BS1及BS2段可以在位时序寄存器CAN_BTR设置它们的时间长度&…

CISP 4.2备考之《安全支撑技术》知识点总结

文章目录 第一节 密码技术第二节 标识和身份鉴别技术第三节 访问控制技术 第一节 密码技术 密码学发展阶段&#xff1a;古典、近代、现代和公钥密码学及特点。 密码系统组成&#xff1a;明文、加密、密钥、解密、密文。 柯克霍夫原则&#xff1a;密钥保密&#xff0c;算法公开…

Stable Diffusion 本地训练端口与云端训练端口冲突解决办法

方法之一&#xff0c;修改本地训练所用的端口 1 首先&#xff0c;进入脚本训练器的根目录 例如&#xff1a;C:\MarkDeng\lora-scripts-v1.7.3 找到gui.py 2 修改端口号 因为云端训练器也是占用28000和6006端口 那么本地改成27999和6007也是可以的 保存退出&#xff0c;运行启动…

NX二次开发常用函数:UF_MODL_ask_feat_......(一)

最近学习NX二次开发发现有一些函数经常使用&#xff0c;俗话说得好&#xff0c;好记性不如烂笔头&#xff0c;现在做一下笔记&#xff0c;帮助理解。 UF_MODL_ask_feat_......所在头文件uf_modl.h 1、UF_MODL_ask_feat_body&#xff08;通过特征查询体&#xff09; 概述&…

liunx centos7 下通过yum删除安装已经安装的php

执行下面命令查看php相关的包 rpm -qa | grep php 只需要卸载几个名为common的包即可&#xff0c;其他同版本依赖会被全部删除&#xff0c;删除php71w-common&#xff0c;71w版本的依赖包全部会被删除。 查看php包的命令 rpm -qa | grep php 或 yum list installed | gre…

鸿蒙APP应用开发教程—超详细的项目结构说明

1. 新建项目 打开DevEco Studio, 选择 Create Project: 1.1 选择模版 Create Project - Choose Template 1.2 配置项目 Create Project - Configure Project 如果使用的是 DevEco 3.X 版本, 可以根据 Compile SDK版本选择不同的模式, 比如: 3.0.0(API 8)及更早 - 仅支持 …

Docker-Image

Docker Docker 镜像是什么为什么需要镜像镜像命令总览docker imagesdocker tagdocker pulldocker pushdocker rmidocker savedocker loaddocker image inspectdocker historydocker importdocker image prunedocker build Docker 镜像是什么 Docker image 本质上是一个 read-on…

图像分类从零开始(1)

尽我所能&#xff0c;总结留给后面的师弟们&#xff01; 1.目标 搭建一个完整的系统&#xff0c;包括图像数据集预处理&#xff0c;训练模型&#xff0c;分类器&#xff0c;优化器&#xff0c;以及结果数据处理。 2.理论 3.实例&#xff08;猫狗分类&#xff09; Gitee代码…

猫,路由器,WIFI

家庭网络常识 1&#xff1a;猫、路由器、wifi_哔哩哔哩_bilibili 入户光纤插到猫上面&#xff0c;网线连接猫和路由器&#xff0c;网线连接路由器和电脑。路由器可以发射WIFI。 手机通过WIFI连接到路由器。 左边是猫&#xff0c;右边是光猫。 &#xff08;modem&#xff09; …

二分算法的变种----查找递增可重复数组边界

public class test {//数组长度a,b,c为8,d为7&#xff1b;static int[] a {3,5,8,8,8,9,9,10};static int[] b {8,8,8,8,8,8,8,8};static int[] c {0,0,0,0,0,0,0,0};static int[] d {0,0,0,0,0,0,0};public static void main(String[] args) {int target 0;System.out.pr…

鸿蒙Harmony应用开发—ArkTS(stateStyles:多态样式)

Styles和Extend仅仅应用于静态页面的样式复用&#xff0c;stateStyles可以依据组件的内部状态的不同&#xff0c;快速设置不同样式。这就是我们本章要介绍的内容stateStyles&#xff08;又称为&#xff1a;多态样式&#xff09;。 概述 stateStyles是属性方法&#xff0c;可以…

python项目格式代码风格

Visual Studio Code 选择使用 black 作为代码格式化工具,保证提交代码风格的统一 1. Install black pip install black2. Install black and isort extension for vscode: 3. 设定black及isort的格式化配置 3.1. ctrl + , 打开配置面板 3.2. 在弹出的json配置中添加,&quo…

周末总结(2024/03/23)

工作 上周末学习了精力管理&#xff0c;但是没有使用成功&#xff0c;总结了一下&#xff0c;有两点没有做到&#xff1a; 接受破烂现状&#xff0c;开始思考 我还没有完全接受自己的失败&#xff0c;很少跟别人分享自己的生活&#xff0c;需要改进 上周计划做的React练习一…

Nginx 全局块配置汇总

前言 nginx.conf 是 nginx 的主配置文件&#xff0c;配置项分为三大块&#xff0c;events 块和 http 块外面的都是全局块 本文记录最常用的全局块配置汇总&#xff0c;对于比较重要或复杂的配置项则另起文章总结&#xff0c;对应配置项中有文章地址 user user 指令用于配置运…

【ORB-SLAM3】在 Ubuntu20.04 上编译 ORM-SLAM3 并使用 D435i 运行测试

【ORB-SLAM3】在 Ubuntu20.04 上编译 ORM-SLAM3 并使用 D435i 运行测试 1 Prerequisites1.1 C11 or C0x Compiler1.2 Pangolin1.3 OpenCV1.4 Eigen3 2 安装 Intel RealSense™ SDK 2.02.1 测试设备2.2 编译源码安装 3 编译 ORB-SLAM34 使用 D435i 运行 ORB-SLAM34.1 运行4.2 运…

Matlab使用教程(持续更新)

1. Matlab Matlab被广泛的应用在数据分析&#xff0c;汽车仿真&#xff0c;机器人以及医学研究等众多方面。 它可以帮助我们理解研究复杂的系统。 在60年代和70年代&#xff0c;计算机使得科学家和工程师完成了以前不可能进行的计算&#xff1b;但是需要懂得计算机编程。 C…

[学习笔记]CNN代码实战

参考资料&#xff1a; 1.https://www.bilibili.com/video/BV1zF411V7xu 2.项目1&#xff1a;基于经典网络架构&#xff08;resnet&#xff09;训练图像分类模型&#xff08;及flask部署&#xff09; 思维导图

vue3项目初始化

初始化项目newsapp VSCode 打开终端&#xff0c;newsapp项目目录&#xff0c;可自定义 vue create newsapp 有提示“因为在此系统上禁止运行脚本”的话&#xff0c;请执行 set-ExecutionPolicy RemoteSigned 执行后再重复执行vue create newsapp 注意选择Vue 3版本 测试项…

【prompt六】MaPLe: Multi-modal Prompt Learning

1.motivation 最近的CLIP适应方法学习提示作为文本输入,以微调下游任务的CLIP。使用提示来适应CLIP(语言或视觉)的单个分支中的表示是次优的,因为它不允许在下游任务上动态调整两个表示空间的灵活性。在这项工作中,我们提出了针对视觉和语言分支的多模态提示学习(MaPLe),以…