线性时间找到第k小的元素:快排应用与BFPRT算法

算法题04:分治法:求第K小元素(线性时间选择算法) 求第k小元素 题目内容: 给定一个线性序列集,要求使用分治法求出其中指定的第 KKK 小的数的值和位置,如给定 nnn 个元素和一个整数 iii,1≤i≤n1≤i≤n1≤i≤n,输出这 nnn 个元素中第 iii 小元素的值及其位置。 一、问题分析(模型、算法设计和正确性证明等) 解决第K小问题有如下几种方法 ①将n个数排序(比如快速排序或归并排序),选取排序后的第k个数,时间复杂度为O(nlog... 阅读详情

问题分析

面对这个问题,最简单的想法是对数据进行排序,然后根据下标即可找到第k小的元素,目前已知的排序算法的最低时间复杂度为 O ( n log ⁡ 2 log ⁡ 2 n ) O(n\sqrt{\log_2 {\log_2 n}}) O(nlog2​log2​n ​),但并不为人熟知。目前应用最广的排序算法的最低时间复杂度为 O ( n log ⁡ 2 n ) O(n\log_2 n) O(nlog2​n)。

但是,作为完美主义者的程序员,需要思考,找到第k小的元素一定需要排序吗?但除了寻找最大或最小的元素之外,我们似乎只能选择排序。那么能否只进行部分排序,便可找到第k小的元素呢?答案是显然的,只需要采用每一趟都能确定一个固定元素的排序算法即可。

思考 O ( n log ⁡ 2 n ) O(n\log_2 n) O(nlog2​n)的排序算法中有哪些算法每一趟可以确定一个固定元素,答案是快速排序和堆排序(不考虑锦标赛排序,堆排序是锦标赛排序的升级版)。这里以快速排序为例,方便引入后面介绍的BFPRT算法,不过还有一个原因是堆排序获取第k小的元素的时间复杂度是 O ( n ) O(n) O(n)的概率小于快速排序。

快排应用

我们知道,快排每一趟都会有随机有一个元素处于最终位置上,故只需在快排中设置一个新的递归出口再加以微改便能返回第k小的元素。
代码如下:
这里采用的快排为随机化快速排序,没有了解过的的朋友可以看一下我的另外一篇博客:升级版快速排序——随机化快速排序

template<typename T>
void partition(T array[],int left,int right,int& mid)
{
	srand(time(0));
	int i = left, j = right, move = rand() % (right - left + 1) + left;
	T temp = array[move];
	array[move] = array[left];
	while (i != j)
	{
		while (array[j] > temp&&j > i) j--;
		if (i < j) array[i++] = array[j];
		while (array[i] < temp&&i < j) i++;
		if (i < j) array[j--] = array[i];

	}
	array[i] = temp;
	mid = i;
}

template<typename T>
T random_quick_sort(T array[], int left, int right,int k)
{
	
	if (k > right - left + 1) exit(7);
	int i;
	partition(array, left, right, i);
	if (k == i - left + 1) return array[i];
	else if (k > i - left + 1) return random_quick_sort(array, i + 1, right, k - i + left - 1);
	else return random_quick_sort(array, left, i - 1, k);
}

这个算法的时间复杂度的确定需要用到指示器随机变量。 E [ T ( n ) ] = E [ ∑ k = 0 n − 1 X k ( T ( m a x E[T(n)]=E[\sum_{k=0}^{n-1}X_k(T(max E[T(n)]=E[∑k=0n−1​Xk​(T(max{ k , n − k − 1 k,n-k-1 k,n−k−1} ) ) + Θ ( n ) ] ))+\Theta(n)] ))+Θ(n)],最终得到 E [ T ( n ) ] = Θ ( n ) E[T(n)]=\Theta(n) E[T(n)]=Θ(n),即该算法的时间复杂度的期望值为 O ( n ) O(n) O(n)
但是存在最坏情况,即每一次划分只能划分出一个部分,即 T ( n ) = T ( n − 1 ) + Θ ( n ) T(n)=T(n-1)+\Theta(n) T(n)=T(n−1)+Θ(n),由等差级数可以得到最坏情况下的时间复杂度为 O ( n 2 ) O(n^2) O(n2)

BFPRT算法

不想写了,困了

重写了这篇博客,新内容已放进去,转到那边去吧:找到第k小的元素【top-k】:快排应用与BFPRT算法

Open3D——RANSAC 三维点云空间直线拟合【2025最新版】 使用RANSAC算法在点云数据中拟合三维空间直线的python代码实现。博客长期更新,本文最新更新时间为:2025年3月23日。 阅读详情

相关推荐

京东商品多维特征提取:基于时空大模型的实时库存预测接口设计

在电商行业,库存管理是供应链的核心环节之一。库存水平过高会导致资金占用、仓储成本增加,而库存水平过低则可能引发缺货风险,影响客户满意度和平台声誉。京东作为中国领先的电商平台,拥有海量的商品数据和复杂的业务场景,传统的库存预测方法难以应对市场动态变化和业务需求。时空大模型作为一种融合时间序列分析和空间特征提取的前沿技术,能够捕捉商品多维特征在时空维度上的变化规律,为实时库存预测提供更精准的决策依据。

FB13713612741的博客 954

线性时间选择—寻找第k小的数(分治算法)

问题描述: 找出一个数组中第K小的元素,时间复杂度为O(n)。 思想 首先,找出数组元素的中位数的中位数,然后利用Partition函数对整个数组进行划分,以数组中中位数的中位数为基准将数组划分为两部分——左边部分的所有数都小于基准,右边部分都大于基准,并返回基准数的下标值。 最后,如果要找到第k小个数,就将k的大小与数组左半边元素的个数(包括基准)进行比较,如果k小于j,则对左边部分进行递归,找第k小个数;若k大于j,则对右边部分进行递归,找第k减去j个小数。 代码如下: #include "stdafx

qyh的博客 5500

【硬件】通俗易懂的讲解晶体管(三极管和MOS管)的工作原理

晶体管是一个简单的元器件,可用于构建许多有趣的项目。在本文中,我将用通俗易懂的语言给您讲解晶体管的工作原理,以便您可以在电路设计中更好的使用静态管。一旦你学习这些基础知识,对以后的设计和使用来说,将会变得非常容易。我们将重点介绍两种最常见的晶体管:双极型晶体管(三极管)和MOSFET。晶体管的工作原理其实是类似于电子开关。它可以打开和关闭电路。一个简单的思考方法是将晶体管视为无源的继电器。晶体管类似于继电器,从某种意义上说,您可以使用它来打开和关闭某些东西。但晶体管也可以部分导通,一般在放大电路中使用,这部

1万+

分治法--线性时间选择(求第k小数)

线性时间选择问题: 给定线性序集中n个元素和一个整数k,1≤k≤n,要求找出这n个元素中第k小的元素,(这里给定的线性集是无序的)。       1、随机划分线性选择         线性时间选择随机划分法可以模仿随机化快速排序算法设计。基本思想是对输入数组进行递归划分,与快速排序不同的是,它只对划分出的子数组之一进行递归处理。 利用随机函数产生划分基准,将数组a[p:r]划分成两个子数组...

zhao2018的博客 8157

别再手动对照了!用Python+ArcGIS Pro一键搞定三调数据转土地三大类

本文介绍如何利用Python和ArcGIS Pro实现三调数据向土地三大类的自动化转换,大幅提升国土空间规划和土地变更调查的工作效率。通过封装分类规则为Python函数并集成到ArcGIS Pro脚本工具中,解决了传统手动操作耗时且易错的问题,适用于大规模数据处理场景。

weixin_29081101的博客 304

线性时间选择(分治):找出一组数中的第k小元素||C++

问题是这样的,有一组数据,请找出这组数据中的第k小的元素。 这个问题为什么叫线性时间选择,我至今没有弄清楚,忘大家能给解释以下。 我在这里给出上述问题的代码: 这里利用的是快排的分割算法。是采用分治法的思想,即将问题划分规模更小的子问题。 代码如下: #include<iostream> using namespace std; int quick(int* arr, int start, int end) { int low = start; int high = end;

李志杰的博客 1180

AD9361 官方例程

文章目录一、官方资料1.1 介绍1.2 下载 和 使用1.3 相关资料二、步骤2.1 在Vivado中构建HDL2.2 在SDK中构建No- OS总结 一、官方资料 1.1 介绍 HDL参考设计介绍:AD9361 HDL Reference Designs 无操作系统介绍:AD9361 No-OS Software 1.2 下载 和 使用 HDL下载:Download HDL 在Vivado中构建HDL:Building HDL No-OS下载:Download No-OS 1.3 相关资料 AD

weixin_44630490的博客 3万+

解决寻找第K小元素问题——三种不同的算法实现

个人原创,禁止转载——Zetrue_Li    问题描述:在一个序列里找出第K小元素 以下程序基于函数 int select_kth_smallest(list q, int k) 实现 :返回向量q中第k最小元的函数 算法一: 基于冒泡排序思想,暴力求解: 基本思路:要求找出第k个最小元素,可以通过在序列中遍历k次,每次找出最小的,并放在序列头。类似泡泡一样,找出第k个大的泡泡(bu...

Zetrue_Li Blog 3万+

学Simulink--基于机器人与自动化系统的场景实例:六自由度机械臂的逆运动学控制仿真

摘要:本文详细介绍了在Simulink中实现六自由度机械臂逆运动学控制的仿真方法。通过构建包含机械臂模型、路径规划器、逆运动学求解器和控制器等模块的系统,利用MATLAB Robotics工具箱进行建模。文章逐步讲解了从模型创建、轨迹规划、逆运动学求解到控制器设计的完整流程,并提供了性能评估标准。该方法能有效验证逆运动学算法,优化机械臂控制策略,提高操作精度和效率,为机器人自动化系统开发提供实用参考。

xiaoheshang_123的博客 230

YOLO26 正式发布源代码!极致速度优化方案, 面向工业级落地的目标检测模型!

YOLO26 作为 Ultralytics 公司于 2025 年 9 月发布的最新一代目标检测模型,在架构设计和技术实现上展现了显著的创新。本文深入分析了 YOLO26 的核心架构改进和技术原理,重点探讨了其在边界框回归、推理流程、损失函数设计和优化算法方面的突破性进展。

魔改工程师的博客 1243

线性时间内找到第k小的元素:快排应用与BFPRT算法

目录问题分析快排应用BFPRT算法 问题分析 面对这个问题,最简单的想法是对数据进行排序,然后根据下标即可找到第k小的元素,目前已知的排序算法的最低时间复杂度为O(nlog⁡2log⁡2n)O(n\sqrt{\log_2 {\log_2 n}})O(nlog2​log2​n​),但并不为人熟知。目前应用最广的排序算法的最低时间复杂度为O(nlog⁡2n)O(n\log_2 n)O(nlog2​n)。 但是,作为完美主义者的程序员,需要思考,找到第k小的元素一定需要排序吗?但除了寻找最大或最小的元素之外,我们

RealCoder的博客 1022

LangChain与LangGraph核心区别解析

LangChain与LangGraph是当前大语言模型(LLM)应用开发中两个紧密相关且极具影响力的开源框架。它们源于LangChain AI公司,设计哲学互补,旨在解决不同维度的LLM工程化问题,共同构成了构建复杂智能应用的强大工具集。

weixin_35774598的博客 1916

C语言线性时间求解第k小,线性时间找到第k小的元素:快排应用与BFPRT算法

问题分析面对这个问题,最简单的想法是对数据进行排序,然后根据下标即可找到第k小的元素,目前已知的排序算法的最低时间复杂度为O(nlog⁡2log⁡2n)O(n\sqrt{\log_2 {\log_2 n}})O(nlog2​log2​n​),但并不为人熟知。目前应用最广的排序算法的最低时间复杂度为O(nlog⁡2n)O(n\log_2 n)O(nlog2​n)。但是,作为完美主义者的程序员,需要思...

weixin_42306501的博客 260

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

BFPRT(中位数的中位数)算法

BFPRT 算法又称为 “中位数的中位数算法”,该算法由 Blum、Floyd、Pratt、Rivest、Tarjan 在1973年提出,最坏时间复杂度为 O(n) TOP-K问题

BENULL的博客 1万+

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

算法13-BFPRT算法

BFPRT 算法是一种高效的查找算法,能够在无序数组中快速找到第 k 小(或第 k 大)元素。通过巧妙的分组和中位数选择,BFPRT 算法在最坏情况下也能保证线性时间复杂度。掌握 BFPRT 算法的核心思想和实现方法,能够帮助你更好地解决实际问题。

mengyoufengyu的博客 1284

第k个小的数 bfprt算法与快排改进

文章目录关于第k小的数 O(N)改进快排思路 O(N) 最坏情况下复杂度为O(n^2)(排序趋近于有序的情况下)bfprt算法(5位MIT大牛的名字首字母缩写)最坏情况下复杂度为O(n)。如何选数这样选 妙在哪里?最坏复杂度为O(N)master公式算法开创一个时代 关于第k小的数 O(N) 改进快排思路 O(N) 最坏情况下复杂度为O(n^2)(排序趋近于有序的情况下) public static int findk(int[] nums,int m,int n ,int k) { int temp

hch977的博客 355

bfprt算法求最小的k个数

bfprt算法是一种经典的线性时间内求最小的第k个数或者最小的k个数的算法。 比如我们要知道销量是前几名商品或者是浏览量最多的前几个网站,我们不需要排序,利用bfprt算法就可以完成。 bfprt算法又称快速选择算法,其思想是利用快速排序的划分来确定位置。此算法经典而优雅,值得我们学习。 步骤          1.将输入的元素划分为5个元素一组,至多有一组不足5个元素。

l-jobs的专栏 1100

【Top -K问题】BFPRT算法与堆

问题背景:在一大堆数中求其前k大或前k小的问题,简称TOP-K问题。 题目链接 这是一类很经典的问题可以有多种解决的方法,这些方法中包含了一些巧妙的数据结构和算法思想。因此简单的排序取值的方法就不再说了。 方法一: 利用快排实现查找。 按照从大到小排序,然后每次计算多少大于标定值的,每次缩小搜查范围。 class Solution(object): def findKthLargest(s...

遍地跑小鸡的博客 346

【算法笔记】bfprt算法

bfprt算法的核心思想bfprt算法也常被称为中位数的中位数算法。它的核心目标是选择一个高质量的“主元”(pivot),使得在后续的划分(Partition)过程中,数组能够被相对均匀地分成两部分。这与快速选择算法思想类似,但bfprt通过一种确定性的方法来选择主元,避免了因主元选择不当而导致性能退化为O(n²)的最坏情况。简单来说,bfprt算法通过分组寻找中位数的中位数来确定主元,从而确保每次划分至少能淘汰一定比例的元素,使得问题规模以几何级数减少,最终保证线性时间复杂度。

u012559967的专栏 673

经典算法 BFPRT算法详解

内容: 1、原始问题 =》 O(N*logN) 2、BFPRT算法 =》 O(N) 1、原始问题 问题描述:给你一个整型数组,返回其中第K小的数 普通解法: 这道题可以利用荷兰国旗改进的 partition 和随机快排的思想:随机选出一个数,将数组以该数作比较划分为 <,=,> 三个部分, 则 = 部分的数是数组中第几小的数不难得知,接着...

weixin_34417183的博客 362

BFPRT

解决的问题: 在一个无需数组中,找到第 k 个大,或者第 k 个小的数 经典思路:类似于快排 我们想要 第 200 小的数 随机选一个数,假设我们选到的数是300,一次遍历,将小于这个数的放左边,等于放中间,大于放右边,得到 x1 和 x2 的位置,x1=300 x2=350 那么 第200小的数 肯定在新数组的 左半部分,我们把左半部分拿出来,再进行这样的划分,最终得到想要的 第 200 小的值...

Venlexi 970

快速选择算法(线性选择算法)+BFPRT算法优化:O(n)复杂度选择第k大的数

什么是快速选择算法? 快速选择算法可以在O(n)的时间复杂度内,选择一个无序随机数组中第k小(大)的元素,它是根据快速排序算法的思想简化而来的。 快速选择算法同样利用了分治回归策略,由于只需要选择出第k小(大)的元素,因此它在分治之后只需要考虑符合条件一边的元素情况。它同样利用了快速排序的分割元素集的思想,随机产生一个基数key,将小于基数分到左边,大于基数的分到右边,然后判断基数位置与选择k个最小(大)元素的大小关系,来确定是下一步是选择左区间还是右区间。 代码: #include<io.

马小超 1213

BFPRT算法

世界十大经典算法之一,由Blum 、 Floyd 、 Pratt 、 Rivest 、 Tarjan提出,这个算法也解了我之前的对某问题的疑惑。 说个题外话,曾经面试的时候被问到的是如何在n个数中找出第二大的数,

shzxrt的专栏 1156

计算机算法-线性寻找第k小(大)元素(Top K)BFPRT算法

计算机算法-线性寻找第k小(大)元素(Top K)BFPRT算法

qq_43838114的博客 599

bfprt算法

BFPRT这一名称来源于该算法的五位作者的首字母,在维基百科上,该算法被称为Median of medians,因为中位数在这里起到了至关重要的角色。 bfprt算法是用来求数组中第k小的元素的算法,bfprt算法可以在O(n)时间内求出答案。在数组范围随机选取一个数,进行partition(荷兰国旗问题,小于放左边,等于放中间,大于放右边),返回等于区的区间range,如果要k小于range[0],说明k在小于区里,再在小于区里进行快排,如果k大于range[1],说明k在大于区里,再在大于区里进行快排,

xiaolu567的博客 883

BFPRT 算法 (TOP-K 问题)——本质就是在利用分组中位数的中位数来找到较快排更合适的pivot元素...

先说快排最坏情况下的时间复杂度为n^2。 正常情况: 最坏的情况下,待排序的记录序列正序或逆序,每次划分只能得到一个比上一次划分少一个记录的子序列,(另一个子序列为空)。此时,必须经过n-1次递归调用才能把所有记录定位,而且第i趟划分需要经过n-i次比较才能找个才能找到第i个记录的位置,因此时间复杂度为 所以BFPRT本质上是在寻找...

djph26741的博客 305
上一篇: 升级版快速排序——随机化快速排序
下一篇: 线性时间内找到第k小的元素:快排应用与BFPRT算法
RealWeakCoder
博客等级 码龄7年 236粉丝 68原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值