当前位置: 首页 > news >正文

Leetcode题解:215,数组中的第k个最大元素,如何使用快速算法解决!

一、题目内容

题目要求给定一个整数数组 nums 和一个整数 k,返回数组中第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。

二、题目分析

输入和输出

输入:

  • 一个整数数组 nums

  • 一个整数 k

输出:

  • 一个整数,表示数组中第 k 个最大的元素。

算法逻辑

使用快速选择算法(Quick Select)来解决这个问题。快速选择算法是基于快速排序算法的变种,用于在 O(n) 的平均时间复杂度内找到数组中的第 k 大元素。

  1. 初始化:

    • 定义一个辅助函数 partition,用于将数组划分为两部分,左边的元素都小于等于某个基准值,右边的元素都大于基准值。

    • 定义主函数 quickSelect,用于递归地找到第 k 大的元素。

  2. 划分数组:

    • partition 函数中,选择数组的最后一个元素作为基准值。

    • 遍历数组,将小于等于基准值的元素移到数组的左边,大于基准值的元素移到右边。

    • 返回基准值的最终位置。

  3. 递归查找:

    • quickSelect 函数中,根据基准值的位置与目标索引 k 的关系,决定是继续在左边子数组查找,还是在右边子数组查找。

    • 如果基准值的位置正好是目标索引 k,则返回基准值。

  4. 终止条件:

    • 当基准值的位置等于目标索引 k 时,返回该位置的值。

三、解题要点

快速选择算法的定义

快速选择算法是基于快速排序算法的变种,用于在 O(n) 的平均时间复杂度内找到数组中的第 k 大元素。它通过划分数组,逐步缩小搜索范围,直到找到目标元素。

算法复杂度
  • 时间复杂度: O(n),在平均情况下,每次划分可以将问题规模减半。

  • 空间复杂度: O(1),只需要常数级别的额外空间。

四、代码解答

以下是使用快速选择算法的 C++ 实现代码:

#include <vector>
#include <algorithm>
#include <iostream>using namespace std;class Solution {
public:int findKthLargest(vector<int>& nums, int k) {// 转换为第 k 小的元素(从 0 开始计数)k = nums.size() - k;return quickSelect(nums, 0, nums.size() - 1, k);}private:// 快速选择算法int quickSelect(vector<int>& nums, int left, int right, int k) {if (left == right) return nums[left];int pivotIndex = partition(nums, left, right);if (k == pivotIndex) {return nums[k];} else if (k < pivotIndex) {return quickSelect(nums, left, pivotIndex - 1, k);} else {return quickSelect(nums, pivotIndex + 1, right, k);}}// 划分数组int partition(vector<int>& nums, int left, int right) {int pivot = nums[right];int i = left;for (int j = left; j < right; ++j) {if (nums[j] <= pivot) {swap(nums[i], nums[j]);++i;}}swap(nums[i], nums[right]);return i;}
};

五、详细注释

快速选择算法的作用

快速选择算法用于在 O(n) 的平均时间复杂度内找到数组中的第 k 大元素。它通过划分数组,逐步缩小搜索范围,直到找到目标元素。

算法逻辑
  1. 划分数组:

    • partition 函数中,选择数组的最后一个元素作为基准值。

    • 遍历数组,将小于等于基准值的元素移到数组的左边,大于基准值的元素移到右边。

    • 返回基准值的最终位置。

  2. 递归查找:

    • quickSelect 函数中,根据基准值的位置与目标索引 k 的关系,决定是继续在左边子数组查找,还是在右边子数组查找。

    • 如果基准值的位置正好是目标索引 k,则返回基准值。

终止条件

当基准值的位置等于目标索引 k 时,返回该位置的值。

六、代码执行过程示例

假设我们有 nums = [3, 2, 1, 5, 6, 4]k = 2

代码执行过程:

  1. 初始化:

    • k = nums.size() - k = 6 - 2 = 4,目标是找到第 4 小的元素。

  2. 划分数组:

    • 初始调用 quickSelect(nums, 0, 5, 4)

    • partition(nums, 0, 5)

      • 选择 nums[5] = 4 作为基准值。

      • 遍历数组,将小于等于 4 的元素移到左边,大于 4 的元素移到右边。

      • 最终数组变为 [3, 2, 1, 4, 6, 5],基准值 4 的位置是 3。

      • 返回基准值的位置 3。

  3. 递归查找:

    • 因为基准值的位置 3 < 4,继续在右边子数组查找。

    • 调用 quickSelect(nums, 4, 5, 4)

    • partition(nums, 4, 5)

      • 选择 nums[5] = 5 作为基准值。

      • 遍历数组,将小于等于 5 的元素移到左边,大于 5 的元素移到右边。

      • 最终数组变为 [3, 2, 1, 4, 5, 6],基准值 5 的位置是 4。

      • 返回基准值的位置 4。

  4. 返回结果:

    • 基准值的位置 4 == 目标索引 4,返回 nums[4] = 5

最终结果:第 2 大的元素是 5。

七、总结

快速选择算法的作用

快速选择算法用于在 O(n) 的平均时间复杂度内找到数组中的第 k 大元素。它通过划分数组,逐步缩小搜索范围,直到找到目标元素。

算法复杂度
  • 时间复杂度: O(n),在平均情况下,每次划分可以将问题规模减半。

  • 空间复杂度: O(1),只需要常数级别的额外空间。

算法逻辑
  1. 划分数组:

    • 选择基准值,将数组划分为两部分。

    • 返回基准值的最终位置。

  2. 递归查找:

    • 根据基准值的位置与目标索引 k 的关系,决定是继续在左边子数组查找,还是在右边子数组查找。

    • 如果基准值的位置正好是目标索引 k,则返回基准值。

终止条件

当基准值的位置等于目标索引 k 时,返回该位置的值。

http://www.dtcms.com/a/329117.html

相关文章:

  • 6 ABP 框架中的事件总线与分布式事件
  • 豆包 + 蘑兔 AI:圆你创作歌曲梦​
  • JavaWeb-Servlet基础
  • 4.0 vue3简介
  • 【深入浅出STM32(1)】 GPIO 深度解析:引脚特性、工作模式、速度选型及上下拉电阻详解
  • 【Docker项目实战】使用Docker部署todo任务管理器
  • [AI React Web]`意图识别`引擎 | `上下文选择算法` | `url内容抓取` | 截图捕获
  • Android 双屏异显技术全解析:从原理到实战的多屏交互方案
  • 开发手记:一个支持自动翻译的H5客服系统
  • TeamViewer 以数字化之力,赋能零售企业效率与客户体验双提升
  • 在线 A2C实践
  • 玩转Docker | 使用Docker部署MediaWiki文档管理平台
  • 大文件上传解决方案
  • React useMemo 深度指南:原理、误区、实战与 2025 最佳实践
  • 【SpringBoot系列-01】Spring Boot 启动原理深度解析
  • C->C++核心过渡语法精讲与实战
  • 深度学习——03 神经网络(2)-损失函数
  • Spring Boot 使用 @NotBlank + @Validated 优雅校验参数
  • react+antd+vite自动引入组件、图标等
  • 适配安卓15(对应的sdk是35)
  • 单片机启动流程详细介绍
  • 开源WAF新标杆:雷池SafeLine用语义分析重构网站安全边界
  • vscode远程服务器出现一直卡在正在打开远程和连接超时解决办法
  • SpringBoot 整合 Langchain4j 系统提示词与用户提示词实战详解
  • IV模型(工具变量模型)
  • 《论文阅读》从特质到移情:人格意识多模态移情反应生成 ACL 2025
  • Dify-17: 扩展模型提供方
  • PyTorch简介
  • layui表格自定义导出数据(选中和全部数据)
  • Debian新一代的APT软件源配置文件格式DEB822详解