左神算法笔记(十四)——BFPRT算法

解决的问题:在一个无序数组中找到第k小的数

快排解法:

  1. 随机选择一个数,利用荷兰国旗问题,将数据分为小于等于大于三块
  2. 利用区分好的数组计算长度,看是否命中,否则看是在哪个块中,在确定块中继续划分,重新回到1。
    对于这种解法而言,如果最差情况是O(N^2),一般情况下,用master公式计算出,最好是O(N)。最后的数学期望是O(N)。

暴力解法:

将整个数组全排列,形成一个有序数组,然后再找到第k个元素。

BFPRT算法:

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

  1. 分组(假设每五个一组,最后剩余的不到五个的一组)
  2. 分组之后每个小组之内排序,跨组不排序,五个数排序,总共需要划分的时间复杂度为O(N)。
  3. 将每个组的中位数拿出,构成新的数组,此时新数组长度为N/5(最后不到五个的可以拿上中位数,也可以拿下中位数)
  4. 调用BFPRT算法,此时递归过程中不再寻找k项,而是选择中间的中位数
  5. 下面就是利用上述num,进行荷兰国旗问题排序
每一步的时间复杂度:

第一步复杂度O(1),
第二步复杂度O(n),
第三部复杂度O(n),
第四步T(N/5),求出p
第五步O(N),
第六步可以确定好是正好还是前往左/右,
此时左边和右边的规模可以估计出来,而不再是未知的。

此时可以估计出至少有多少个数比p要大,或者比p小。
通过计算可以得知,按照三次排序,第一次排序N/5个人被挑选出来,再进行排序,此时N/10比数值大,比中位数大的数值此时加入到原始数组中,所以此时N/10+2N/10=3N/10,所以此时最多有7N/10比p大或者小。

代码实现

//用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方法主体部分
public static int bfprt(
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值