LeetCode HOT100系列题解之数组中的第K个最大元素(7/100)

news2024/9/16 9:45:04

目录

题目:第K个最大元素. - 力扣(LeetCode)

题解

方法一 快速排序

方法二 桶排序

思考:各个排序的思路,以及时间复杂度是多少?

1. 冒泡排序(Bubble Sort)

2. 选择排序(Selection Sort)

3. 插入排序(Insertion Sort)

4. 快速排序(Quick Sort)

5. 归并排序(Merge Sort)

6. 堆排序(Heap Sort)


题目:第K个最大元素. - 力扣(LeetCode)

题解

方法一 快速排序

第K大数本身,这是一个经典的快速排序问题,以此做一个快速排序的复习。

需要注意的是,这个题严格规定时间为O(N),快排则是期望为线性O(N)的。

快速排序的思路:

选取一个基准(pivot),通过一趟排序将数据分成两部分:左边的都小于等于基准,右边的都大于基准。然后递归地对左右两部分进行快速排序。

举例(如果有错,理解就可以):

6 5 3 4 2 1

l = 0,  r = 5

i = -1, j = 6

x = q[0] = 6

while循环结束

i = 0 j = 5

swap(q[0], q[5])

k=4<=5,继续,递归走if

1 5 3 4 2

l = 0, r = 5

i = - 1,j = 6

x = q[0] = 1

while(i < j)

while(q [ ++ i ] < 1) 不存在 i = 0

while(q [ - - j ] > 1) j = 0

k = 4 >= 0

走else l = j + 1 = 1, r = 5

1 5 3 4 2 6

l = 1, r = 5

x = q[1] = 5

i = 0, j = 6

while(i < j)

while(q [ ++ i ] < 5) 不存在 i = 1

while(q [ - - j ] > 1) j = 4

swap(q[1], q[4])

1 2 3 4 5 6

l = 1, r = 4

i = 0, j = 5

x = q[1] = 2

i = j = 1

l = 2 ,r = 4

···

l = 4, r = 4 return q[4]

代码: 

class Solution {
public:
    int quick_select(vector<int>& q, int l, int r, int k) {
        if (l == r) return q[l];  // 只有一个元素时直接返回

        int i = l - 1, j = r + 1;
        int x = q[l];  // 选择第一个元素作为基准
        while (i < j) {
            while (q[++i] < x);  // 向右找第一个不小于 x 的元素
            while (q[--j] > x);  // 向左找第一个不大于 x 的元素
            if (i < j) swap(q[i], q[j]);  // 交换
        }

        // 判断 k 在左半部分还是右半部分
        if (k <= j) return quick_select(q, l, j, k);  // 在左半部分查找
        else return quick_select(q, j + 1, r, k);  // 在右半部分查找
    }

    int findKthLargest(vector<int>& nums, int k) {
        int n = nums.size();
        return quick_select(nums, 0, n - 1, n - k);  // 查找第 n-k 个最小的元素
    }
};

方法二 桶排序

该题给出的数据范围以及时间限制,实际上桶排序更符合要求。

代码:  

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        vector<int> s(20010, 0);  // 初始化计数数组,大小为20010,用于存储[-10000, 10000]范围内的数字频率

        // 统计每个元素出现的次数
        for (int num : nums) {
            s[num + 10000]++;  // 将原数组元素映射到[0, 20010)的范围
        }

        // 从大到小遍历查找第k大元素
        for (int i = 20009; i >= 0; i--) {  // 从最大值开始遍历
            k -= s[i];
            if (k <= 0) {
                return i - 10000;  // 将索引还原为原数组的数值
            }
        }

        return -1;  // 如果没有找到(理论上不应到达这里)
    }
};

思考:各个排序的思路,以及时间复杂度是多少?

1. 冒泡排序(Bubble Sort)

  • 思路:重复地遍历要排序的列表,每次比较相邻的两个元素,如果它们的顺序错误就交换它们。每一轮遍历后,最大的元素都会“冒泡”到未排序部分的最后。
  • 时间复杂度:最坏情况下是 O(n^2)。
  • 稳定性:稳定(相同元素的相对位置不会改变)。
  • 特点:实现简单,但效率较低,适合小规模数据或教学用途。

2. 选择排序(Selection Sort)

  • 思路:每次从未排序部分选出最小(或最大)的元素,放到已排序部分的末尾。通过遍历找到最小值或最大值的位置,然后交换到正确的位置。
  • 时间复杂度:最坏情况下是 O(n^2)。
  • 稳定性:不稳定(相同元素的相对位置可能改变)。
  • 特点:比较次数固定为 n(n−1)/2,交换次数较少。

3. 插入排序(Insertion Sort)

  • 思路:将元素逐一插入到已排序部分的合适位置。初始时只有一个元素是已排序的,然后依次将未排序元素插入到前面已排序的部分。
  • 时间复杂度:最坏情况下是O(n^2),最优情况下是 O(n)(当输入已经有序)。
  • 稳定性:稳定。
  • 特点:适合小规模或基本有序的数据。

4. 快速排序(Quick Sort)

  • 思路:选取一个基准(pivot),通过一趟排序将数据分成两部分:左边的都小于等于基准,右边的都大于基准。然后递归地对左右两部分进行快速排序。
  • 时间复杂度:平均是 O(nlog⁡n),最坏情况下是 O(n^2)(当每次选的基准都是最大或最小值)。
  • 稳定性:不稳定。
  • 特点:在大多数情况下是最快的基于比较的排序算法,广泛使用。

5. 归并排序(Merge Sort)

  • 思路:将待排序数组分成两部分,递归地对两部分进行归并排序,然后将两部分合并成一个有序数组。
  • 时间复杂度:始终是O(nlogn)。
  • 稳定性:稳定。
  • 特点:适合大规模数据排序,特别是外部排序(如磁盘数据),但需要额外的空间来存储临时数据。

6. 堆排序(Heap Sort)

  • 思路:利用堆这种数据结构(通常是大顶堆或小顶堆)来排序。首先构造一个大顶堆(或小顶堆),然后反复将堆顶元素取出并重新调整堆,直到所有元素有序。
  • 时间复杂度:最坏情况下是 O(nlog⁡n)。
  • 稳定性:不稳定。
  • 特点:不需要额外的空间,适合大数据的内存排序。

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

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

相关文章

C++ 定时器

这是第一次独立设计一个模块&#xff0c;从接口定义&#xff0c;模块组合到多线程并发可能遇到的各种问题&#xff0c;虽然定时挺简单的&#xff0c;但是想设计精度高&#xff0c;并且能应对高并发似乎也不是很容易&#xff0c;当然&#xff0c;最后没有测试定时器的代码&#…

架构模式:MVC

引言 MVC&#xff0c;即 Model&#xff08;模型&#xff09;-View&#xff08;视图&#xff09;-Controller&#xff08;控制器&#xff09;&#xff0c;是广泛应用于交互式系统中的典型架构模式&#xff0c;尤其在 GUI 和 Web 应用中。 MVC 的概念源自 GOF&#xff08;Gang …

JS解密工具之**如何续期 Charles 的 SSL 证书**

本文由 jsjiami加密/一键JS解密 独家赞助 有问题请私聊加密官方客服 Charles 是一款常用的 HTTP 代理工具&#xff0c;用于调试网络请求。然而&#xff0c;Charles 的 SSL 证书会定期过期&#xff0c;如果 SSL 证书失效&#xff0c;你将无法对 HTTPS 请求进行抓包。本文将详细…

SQL语句中in条件超过1000怎么办?

博客主页: 南来_北往 系列专栏&#xff1a;Spring Boot实战 引言 当遇到SQL语句中IN条件超过1000个的情况时&#xff0c;可以采取以下几种策略来有效处理这一问题&#xff1a; 使用临时表&#xff1a;将IN列表中的值存储在临时表中&#xff0c;并将该临时表与查询表进行J…

【Python 千题 —— 算法篇】寻找最长回文子串

Python 千题持续更新中 …… 脑图地址 &#x1f449;&#xff1a;⭐https://twilight-fanyi.gitee.io/mind-map/Python千题.html⭐ 题目背景 回文串是指一个字符串从左到右和从右到左读都是一样的。寻找一个字符串中的最长回文子串是许多经典算法问题之一&#xff0c;广泛应…

2024年9月最新界面:自己如何在电脑上注册新的Google谷歌账号,图文详解和关键点解析、常见问题

有一些朋友需要通过谷歌账号来工作、学习或娱乐&#xff08;例如很多游戏需要用谷歌账号来注册和使用&#xff09;&#xff0c;但是不知道如何注册谷歌账号&#xff0c;或者知道如何注册&#xff0c;但是对于一些步骤或者注意事项不太熟悉&#xff0c;导致注册不成功&#xff0…

什么是LED智能会议一体机?COB超微小间距LED会议一体机大势所趋

LED智能会议一体机&#xff0c;作为现代会议室革新的核心装备&#xff0c;正逐步颠覆传统会议模式的界限。它不仅仅是一台集成了高清显示、触控互动、音视频处理及远程协作等功能于一体的智能设备&#xff0c;更是推动会议效率与体验双重飞跃的关键力量。随着技术的不断进步&am…

【重学 MySQL】十八、逻辑运算符的使用

【重学 MySQL】十八、逻辑运算符的使用 AND运算符OR运算符NOT运算符异或运算符使用 XOR 关键字使用 BIT_XOR() 函数注意事项 注意事项 在MySQL中&#xff0c;逻辑运算符是构建复杂查询语句的重要工具&#xff0c;它们用于处理布尔类型的数据&#xff0c;进行逻辑判断和组合条件…

【Protobuf】初识protobuf以及详细安装教程

W...Y的主页 &#x1f60a; 代码仓库分享 &#x1f495; 目录 序列化概念 ProtoBuf是什么 ProtoBuf在window下的安装 下载ProtoBuf编译器 配置环境变量 ​编辑 检查是否配置成功 ​编辑 ProtoBuf在Linux下的安装 下载ProtoBuf 安装ProtoBuf 序列化概念 首先我们…

小白开发中遇到的问题和解决方案

小白开发中遇到的问题和解决方案 文章目录 小白开发中遇到的问题和解决方案问题一 问题一 问题&#xff1a;端口别占用可能开开启多个应用 解决方法–在cmd执行下方红框中的命令关闭所有应用

MyBatis-MappedStatement什么时候生成?QueryWrapper如何做到动态生成了SQL?

通过XML配置的MappedStatement 这部分MappedStatement主要是由MybatisXMLMapperBuilder进行解析&#xff0c;核心逻辑如下&#xff1a; 通过注解配置的MappedStatement 核心逻辑就在这个里面了&#xff1a; 继承BaseMapper的MappedStatement 我们看看这个类&#xff0c;里…

idea如何配置模板

配置生成代码指令模板 注&#xff1a;我们常用的有sout,main等指令 第一步打开设置面板 1)按如下操作 2&#xff09;或者CtrlAltS快捷键直接弹出 第二步找 Editor>LiveTemplates 如下图 第三步创建模板 步骤如下 1&#xff09;创建分组名字 2)分组名字 3&#xff09;创…

如何用Docker运行Django项目

本章教程,介绍如何用Docker创建一个Django,并运行能够访问。 一、拉取镜像 这里我们使用python3.11版本的docker镜像 docker pull python:3.11二、运行容器 这里我们将容器内部的8080端口,映射到宿主机的80端口上。 docker run -itd --name python311 -p

pycharm如何安装selenium

在pycharm中打开一个项目后,点击Setting(ALTCtrlS快捷键) 然后点击install package完成后点击关闭这个窗口,就可以在代码中使用selenium了 成功后出现如下界面 编写一段正常可以运行操作chorme浏览器的 from selenium import webdriver # 指定ChromeDriver的路径driver we…

关于 PC打开“我的电脑”后有一些快捷如腾讯视频、百度网盘、夸克网盘、迅雷等各种捷方式在磁盘驱动器上面统一删除 的解决方法

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/142029325 长沙红胖子Qt&#xff08;长沙创微智科&#xff09;博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV…

淘宝开放平台交易类API解析以及如何测试?

调用淘宝开放平台的订单接口&#xff0c;主要可以通过以下几种途径进行&#xff1a; 1. 直接使用淘宝开放平台提供的API接口 步骤概述&#xff1a; 注册淘宝开放平台账号&#xff1a;首先&#xff0c;你需要在淘宝开放平台注册一个开发者账号。创建应用&#xff1a;在注册并…

Unity3D 小案例 像素贪吃蛇 01 蛇的移动

Unity3D 小案例 像素贪吃蛇 第一期 蛇的移动 像素贪吃蛇 今天来简单制作一个小案例&#xff0c;经典的像素贪吃蛇。 准备 首先调整一下相机的设置&#xff0c;这里使用灰色的纯色背景&#xff0c;正交视图。 接着&#xff0c;创建一个正方形&#xff0c;保存为预制体&#…

位运算技巧总结

一、常见位运算操作 1、基础位运算 & 按位与 有0则0 | 按位或 有1则1 ^ 按位异或 相同为0 不同为1 2、确定数n的二进制位中第x位是0还是1 目的&#xff1a;是0返回0&#xff0c;是1返回1 (n >> x) & 1 思路&#xff1a;1除了第一位其他位都是0&a…

01初识FreeRTOS【前情回顾篇】

为什么要使用FreeRTOS&#xff1f; 裸机轮询无法避免两个函数相互影响的问题&#xff0c;例如我们使用单片机在进行裸机开发时&#xff0c;我们使用了Delay延时函数&#xff0c;这时我们无法再执行其他的功能代码&#xff0c;需要等延时时间结束再执行其他代码&#xff0c;而使…

通过域名无法访问不到网站,IP可正常访问(DNS污染)

一 DNS被污染 就在刚刚突然访问不到csdn&#xff0c;域名无法访问如下图&#xff1a; 确认DNS是否解析有问题 1 ping 域名 先ping一下域名&#xff0c;ping 域名后得到ip, ping通了如下图&#xff1a; 2 使用IP访问测试 通过ip再访问网站&#xff0c;ip可以正常访问如下图&…