LeetCode Hot100 215. 数组中的第K个最大元素

题目

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

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

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

示例 1:

复制代码
输入: [3,2,1,5,6,4], k = 2
输出: 5

示例 2:

复制代码
输入: [3,2,3,1,2,4,5,5,6], k = 4
输出: 4

提示:

  • 1 <= k <= nums.length <= 105
  • -104 <= nums[i] <= 104

代码&注释

java 复制代码
class Solution {
    /**
     * 查找数组中第 k 个最大的元素(即第 k 大)
     * 
     * 思路:先对整个数组进行升序排序,然后第 k 大就是倒数第 k 个元素,
     *       即索引为 nums.length - k 的元素。
     * 
     * 注意:此方法时间复杂度为 O(n log n),不是最优解(最优可用快速选择,平均 O(n)),
     *       但逻辑简单、易于理解。
     * 
     * @param nums 输入数组
     * @param k 第 k 大(k 从 1 开始计数)
     * @return 第 k 个最大的元素;若输入非法,返回 0
     */
    public int findKthLargest(int[] nums, int k) {
        // 边界检查:数组为空、长度为 0 或 k 超出范围
        if (nums == null || nums.length == 0 || k > nums.length) {
            return 0;
        }
        
        // 对整个数组进行升序快速排序
        quick_sort(nums, 0, nums.length - 1);
        
        // 排序后,第 k 大的元素位于倒数第 k 个位置
        // 例如:[1,2,3,4,5],第 2 大是 4,索引 = 5 - 2 = 3
        return nums[nums.length - k];
    }

    /**
     * 快速排序(递归实现,原地排序)
     * 
     * 采用"三路划分"思想的简化版(实际是标准双指针分区)
     * 目标:将数组 [l, r] 区间按升序排列
     * 
     * @param nums 待排序数组
     * @param l 左边界(包含)
     * @param r 右边界(包含)
     */
    public void quick_sort(int[] nums, int l, int r) {
        // 递归终止条件:区间无效(只有一个元素或空)
        if (l >= r) {
            return;
        }

        // 初始化左右指针
        int i = l; // 左指针,从左向右扫描
        int j = r; // 右指针,从右向左扫描

        // 选择基准值(pivot):取中间位置的元素,避免最坏情况(如已排序数组)
        // 使用 l + (r - l) / 2 防止整数溢出(等价于 (l + r) / 2,但更安全)
        int pivot = nums[l + (r - l) / 2];

        // 分区过程:将小于 pivot 的放左边,大于 pivot 的放右边
        while (i <= j) {
            // 从左边找到第一个 >= pivot 的元素
            while (nums[i] < pivot) {
                i++;
            }
            // 从右边找到第一个 <= pivot 的元素
            while (nums[j] > pivot) {
                j--;
            }
            
            // 如果两个指针未交错,说明找到了一对需要交换的元素
            if (i <= j) {
                // 交换 nums[i] 和 nums[j]
                int temp = nums[i];
                nums[i] = nums[j];
                nums[j] = temp;
                
                // 移动指针,继续扫描
                i++;
                j--;
            }
        }

        // 递归处理左右两个子区间
        // 注意:此时 j 是左半部分的右边界,i 是右半部分的左边界
        if (l < j) {
            quick_sort(nums, l, j);   // 排序左半部分 [l, j]
        }
        if (i < r) {
            quick_sort(nums, i, r);   // 排序右半部分 [i, r]
        }
    }
}
相关推荐
聪明蛋子哟5 分钟前
不仅仅是向量检索:结合知识图谱与Tool Calling的混合增强生成(Hybrid RAG)方案
人工智能·算法·知识图谱
Pniubi6 分钟前
力扣55跳跃游戏(贪心)
算法·leetcode·游戏
jyyyx的算法博客36 分钟前
传球游戏【思维】
算法
FL16238631291 小时前
关于2026年南昌大学811信号与系统最后一题电路系统解题思路
算法
殷色玫瑰1 小时前
C++ STL:map 与 set 详解——从底层红黑树到实际应用
c语言·数据结构·c++·算法·visualstudio·rpc
行者全栈架构师1 小时前
【鸿蒙心迹】鸿蒙网络请求架构实战——@ohos.net.http 到 Axios 封装、拦截器与统一错误处理(HarmonyOS 7.x)
前端·算法·架构
小宋10211 小时前
OpenTelemetry GenAI可观测性实战:串起模型、工具、Token与错误
java·人工智能·算法·贪心算法
嫂子开门我是_我哥1 小时前
青少年抑郁、焦虑、失眠与自杀相关表现的症状联系:一篇网络分析论文所使用的算法深度解读
论文阅读·算法·论文笔记
字节跳动的猫1 小时前
LikeShop 商品评价体系二开:追评、晒图审核与评价标签筛选功能开发
运维·数据结构·数据库
渊鱼L1 小时前
CAD随机颗粒插件2D V2.0 更新说明
算法