算法笔记——左神进阶(2)BFPRT算法:TOP-K问题(查找第k小的数)+ 窗口内最大值的求解

本文介绍了BFPRT算法,一种用于在数组中查找第k小元素的高效方法,它改进了快速排序的荷兰国旗问题。此外,还讨论了如何使用双端队列解决窗口内最大值的实时计算问题,包括窗口滑动时的最大值更新策略,确保在O(N)的时间复杂度内完成。
摘要由CSDN通过智能技术生成

一、BFPRT算法

在一个数组中找出第k大的数

1、暴力解法:先排序,再找
2、快速排序:参考荷兰国旗问题,随机选数,分为左中右三个部分,然后按数量选择左边或右边区域,继续按荷兰国旗问题分三块,直到取到序号k在中间等于区域,则此时的中间数就是第k大的数。
3、BFPRT算法:

BFPRT算法跟快排的算法只有在选取划分值的情况上不同,其他全部一样。
【步骤】

  1. 分组(假设每五个一组,最后剩余的不到五个的一组) O(1)
  2. 分组之后每个小组之内排序,跨组不排序,五个数排序,总共需要划分的时间复杂度为O(N)。
  3. 将每个组的中位数拿出,构成新的数组,此时新数组长度为N/5(最后不到五个的可以拿上中位数,也可以拿下中位数) O(N)
  4. 调用BFPRT算法,此时递归过程中不再寻找k项,而是选择中间的中位数 T(N/5)
  5. 下面就是利用上述num,进行荷兰国旗问题排序 O(N)
  6. 选择走左边或者走右边
    之所以要这样来选出中位数作为基准值,是因为这样分组后的左右规模就是确定了的,此时估计至少有多少个数比k更大,则确定了左右部分的最大规模。

【代码】

//用BFPRT方法得到第k个最小的值
public static int getMinKthByBFPRT(int[] arr,int k ){
   
	int[] copyArr = copyArray(arr);
	//得到数组中第k-1位置上的值就是第k小的值
	return bfprt(copyArr,0,copyArr.length-1,K-1);
}
//bfprt方法主体,在bigin和end范围上求第i小的数
public static int bfprt(int[] arr,int begin,int end,int i){
   
	if(begin == end){
   
		return arr[begin];
	}
	//求中位数的中位数
	int pivot = medianOfMedians(arr,begin,end);
	//求完第二轮的中位数之后就开始进行划分
	int[] privotRange = partition(arr,begin,end,pivot);
	//正好i位置等于相等部分则返回
	if(i>= pivotRange[0] && i <= pivotRange[1]){
   
		return arr[i];
		//i小于排序起始位置的情况,走左边
	}else if(i<pivotRange[0]){
   
		return bgprt(arr,begin,pivotRange[0]-1,i);
	}else{
   
		//i大于终止位置的情况,走右边
		return bfprt(arr,pivotRange[1]+1,end,i);
	}
}
	
public static int medianOfMedians(int[] arr,in
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值