使用分治法查找无序序列中第k小的数

Quepierts 2024-10-19 17:40:42

1、描述找第k小的数的分治算法

1.1、问题描述

给定长度为n的无序数组,找出其中第k小的数

 

1.2、算法思路

该问题可以依照快排算法的划分算法来进行求解,即分治思想:

  1. 通过选定数组中一个元素作为基准点(pivot),将数组划分为两部,使得:左半部所有数比基准点小 ,右半部比基准点大。划分后的数组不会确保所有数都在其最终位置,但肯定的是,基准元素是在其最终位置上的。
  2. 在划分后,返回该基准点的下标,如果等于 k-1(即第k的元素的下标),则找到了该数,可直接返回。否则,若大于,将范围缩小至左半边,小于则缩小至右半端,并进行重复查找。

 

1.3、具体思路

此处使用自然语言进行描述,因为写出的伪代码与实际代码无异

划分:

  1. 将数组子序列 left ~ right 中第一个值选为基准值
  2. 通过把左右指针逐步向中间靠拢:小于pivot的元素移动至右方,大于pivot的元素移动至左方
  3. 在左右指针重合后返回pivot的下标

查找:

  1. 通过划分函数确定一个元素的位置:若等于 k-1,直接返回,否则循环查找:
    1. 如果pivot的值大于 k-1,只需往左方查找
    2. 如果pivot的值小于 k-1,只需往右方查找

2、算法的时间复杂度

递归关系式:T(n) = T(n/2) + O(n)

2.1、最好时间复杂度

当每次选择的基准点都能正好将数组均分时,算法的时间复杂度为O(n),因为每次划分都会将问题规模减半,递归深度为O(logn)

 

2.2、最坏时间复杂度

如果每次选择的基准元素是极端值,导致每次只能减少一个元素,此时的时间复杂度为O(n²)


3、心得

分治法的核心在于“分而治之”,它将一个复杂问题拆分为若干规模较小且独立的子问题,通过递归的方式逐个解决这些子问题,最后再将子问题的解组合成原问题的解。其巧妙的点在于,将原问题的复杂度转移到了多个小的问题上,让求解过程更加简单和高效。当然,在一些情况下,在规划和设计不合理的情况下,分治法也不一定比其他方法来得高效。

...全文
175 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

434

社区成员

发帖
与我相关
我的任务
社区描述
广东外语外贸大学信息科学与技术学院
算法 高校
社区管理员
  • brisksea
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧