算法47,分治快排,第K大

1. 代码逻辑解析

  • 随机选基准值 :nums[new Random().nextInt(r-l+1)+l] 随机选取基准值 key,避免有序数组下的最坏情况。
  • 三路分区 :将当前区间 [l, r] 划分为三部分:小于 key、等于 key、大于 key。
    • left 指向大于 key 区域的末尾,right 指向小于 key 区域的开头。
    • 遍历数组,将元素交换到对应区域。
  • 分类讨论 :
    • b 为大于 key 的元素个数,c 为等于 key 的元素个数。
    • 若 c >= k(第 k 大元素在等于 key 的区域),直接返回 key。
    • 若 b >= k(第 k 大元素在大于 key 的区域),递归左半部分(大于 key 的区域)。
    • 否则(第 k 大元素在小于 key 的区域),递归右半部分,并更新 k = k - b - c。

2. 复杂度分析

  • 时间复杂度 :平均 O(n),最坏情况(每次分区极不均匀)为 O(n²)。随机化基准值可有效避免最坏情况。
  • 空间复杂度 :O(log n)(递归栈深度,随机化下平均对数级)。

3. 优缺点评价

  • 优点:利用了三路快排处理重复元素的优势,逻辑严谨,效率较高。
  • 缺点 :
    • 每次递归都 new Random(),有一定性能开销。
    • 分区逻辑变量较多(如 left-1、right+1),容易在边界条件上出错。

4. 优化与替代方案

  • 优化建议 :
    • 将 Random 实例提取为全局静态变量,避免频繁创建。
    • 当区间较小时(如长度 < 10),可切换为插入排序以提升缓存命中率。
  • 替代方案 :
    • 最小堆 :维护一个大小为 k 的最小堆,时间复杂度 O(n log k),空间复杂度 O(k),适合处理海量数据。
    • 快速选择(双路分区):常规的双指针分区同样可以实现 O(n) 的平均时间复杂度。

5. 注意事项

  • 题目明确"第 k 个最大元素"允许重复(如示例 2),三路快排恰好适合此场景。
  • 递归终止条件 if(l==r) return nums[l]; 确保了区间缩小到单个元素时正确返回。
相关推荐
古法老登瞎折腾6 小时前
大数据智能运维实战(十一):运维 MCP 的工程化——权限、限流、审计与错误处理
java·大数据·运维·spring ai·mcp
智能运维指南7 小时前
研制过程“两张皮“怎么破:研制一体化支撑平台的定位、能力边界与落地前提
java·前端·人工智能·嘉为蓝鲸
yz_aiks8 小时前
Spring AI 2.1 ChatMemory 已过时用什么替代:迁移到 Session Memory 实战(JDBC 存储与会话压缩)
java·spring boot·大模型·ai agent·spring ai
金銀銅鐵8 小时前
[Java] 用 GUI 展示 EnumMap 增删键值对时的内部变化
java·后端·ai编程
学长毕设8 小时前
基于SpringBoot的上门洗车服务系统设计与实现
java·spring boot·后端
jason成都8 小时前
RTKLIB-Java 多基线联合RTK:FIX率从0%到91.5%的三层根因修复
java·gnss·rtklib·rtklib_java
鱼宵9 小时前
Stream 终端操作一次讲透:collect、count、reduce 怎么选
java·stream·终端操作
白山编程大哥9 小时前
Java 后端如何优雅地把 List 集合返回给前端
java·前端·list
Linux运维技术栈9 小时前
CVE-2026-91403 高危漏洞修复:Rocky Linux 9 多版本 JDK 环境清理实操
java·linux·运维
On The Road :9 小时前
Java 多线程详解:从入门到线程安全
java·python·安全