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

算法刷题记录——LeetCode篇(3.2) [第211~212题](持续更新)

更新时间:2025-04-04

  • 算法题解目录汇总:算法刷题记录——题解目录汇总
  • 技术博客总目录:计算机技术系列博客——目录页

优先整理热门100及面试150,不定期持续更新,欢迎关注!


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 <= 10^5
  • -10^4 <= nums[i] <= 10^4

方法:三向切分快速选择法

利用快速选择算法结合三向切分,高效定位第K大元素。

  1. 三向切分

    • 将数组分为三个区域:大于基准值、等于基准值、小于基准值;
    • 采用类似荷兰国旗问题的分区方式,一次遍历完成分类;
  2. 递归选择

    • 根据当前分区后的元素数量分布,决定递归处理方向;
    • 大于区域元素足够时递归处理前部;
    • 数量不足但包含等于区域时直接返回基准值;
    • 否则递归处理后部并调整k值;

随机选择基准值避免最坏情况,每次递归至少排除一个区域元素。

代码实现(Java):

class Solution {
    public int findKthLargest(int[] nums, int k) {
        return quickSelect(nums, 0, nums.length - 1, k);
    }
  
    private int quickSelect(int[] nums, int left, int right, int k) {
        if (left == right) {
            return nums[left];
        }
      
        Random rand = new Random();
        int pivotIndex = left + rand.nextInt(right - left + 1);
        int pivot = nums[pivotIndex];
      
        // 三向切分(荷兰国旗问题)
        int low = left;
        int high = right;
        int mid = left;
      
        while (mid <= high) {
            if (nums[mid] > pivot) {  // 大于pivot的交换到前部
                swap(nums, low, mid);
                low++;
                mid++;
            } else if (nums[mid] < pivot) { // 小于pivot的交换到后部
                swap(nums, mid, high);
                high--;
            } else {  // 等于时继续后移
                mid++;
            }
        }
      
        // 计算各区域元素数量
        int gtCount = low - left;       // 大于pivot的数目
        int eqCount = high - low + 1;   // 等于pivot的数目
      
        if (k <= gtCount) {             // 目标在大于区域
            return quickSelect(nums, left, low - 1, k);
        } else if (k <= gtCount + eqCount) { // 目标在等于区域
            return pivot;
        } else {                        // 目标在小于区域
            return quickSelect(nums, high + 1, right, k - gtCount - eqCount);
        }
    }
  
    private void swap(int[] nums, int i, int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
}

复杂度分析

平均时间复杂度 O(n),最坏情况 O(n^2)


声明

  1. 本文版权归 CSDN 用户 Allen Wurlitzer 所有,遵循CC-BY-SA协议发布,转载请注明出处。
  2. 本文题目来源 力扣-LeetCode ,著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
http://www.dtcms.com/a/111688.html

相关文章:

  • CExercise_05_1函数_1.1素数(要对键盘录入的数据做参数校验)
  • 游戏引擎学习第204天
  • 使用 .NET 9 和 Azure 构建云原生应用程序:有什么新功能?
  • ArkTs的UI装饰器(自定义组件生命周期、页面组件生命周期、所有UI装饰器使用及示例)
  • C++ | C++11知识点
  • react redux的学习,单个reducer
  • Spring-IOC部分
  • python __init__文件的作用
  • (51单片机)矩阵按键密码锁表白(C语言代码编撰)(矩阵按键教程)(LCD1602浅教程)
  • Python数据结构之有序列表
  • docker使用汇总
  • 【YOLO系列(V5-V12)通用数据集-工程用车检测数据集】
  • MINIQMT学习课程Day8
  • 解锁大数据可视化设计,让数据会 “说话”
  • Docker安装、配置JDK17
  • 程序化广告行业(59/89):广告验证与反作弊实战技巧
  • HTML jQuery 项目 PDF 批注插件库在线版 API 示例教程
  • PostgreSQL的扩展(extensions)-常用的扩展-pg_dirtyread
  • 55.基于springboot+vue的汽车租赁管理系统
  • Flink CDC Pipeline mysql to doris
  • 关于JVM和OS中的指令重排以及JIT优化
  • 小刚说C语言刷题——第14讲 逻辑运算符
  • Jetpack Compose `ACTION_HOVER_EXIT` 事件异常解决方案
  • 纯个人整理,蓝桥杯使用的算法模板day2(0-1背包问题),手打个人理解注释,超全面,且均已验证成功(附带详细手写“模拟流程图”,全网首个
  • MySQL-SQL-DDL语句、表结构创建语句语法、表约束、表数据类型
  • Dive into Deep Learning - 2.4. Calculus (微积分)
  • Netty——连接超时 与 断开重连
  • Linux命令-grep
  • 人工智能爬虫导致维基共享资源带宽需求激增 50%
  • 计算机系统---GPU