Top-K问题,BFPRT算法浅析

TOP-K问题解决思路:

1.排序,选取前n个数(或后n个数)
2.bfprt算法


1.通过排序算法:最好的时间复杂度为O(nlogn),除非选用基数排序,用极多空间换时间的就不说啦。其实原因很简单,你需要的是最大的k个数,而排序是将所有数排序再选取前n个数,这时想想如果能找到第n大的数,就能找到所有小于它的数。

2.bfprt算法:

(1)将数组分为n/5(不够5的进1)组,对于每一组取中位数。(若元素数为偶数个,则取中间靠前那个)

(2)递归地使用第一步将取得的中位数再取中位数,直到剩下最后一个中位数。

(3)将数组中小于该中位数的数移到它之前,大于该中位数的移到它之后,并返回此时中位数在数组中的位置index。(类似于快速排序的partion)

(4)  如果index == k ,则该中位数就是第k大的元素
  如果index < k ,则第k大的元素下标一定大于index,递归求index之后的数组
  如果index > k,则第k大的元素下标一定小于index,递归求index之前的数组


Java代码:

<1>bfprt代码:(因为需要递归,参数中还有起始下标l和结束下标r)
public static int bfprt(int[] a,int l,int r,int k) {
		int mid = findMid(a,l,r);
		int index = findIndex(a,mid);
		int i = partion(a,l,r,mid,index);
		if (i == k) return a[i];
		if (i > k) return bfprt(a,l,i,k);
		return bfprt(a,i+1,r,k);
	}
<2>findMid:寻找中位数的递归算法
public static int findMid(int[] a,int l,int r) {
		if (l==r) return a[l];
		int size = (r-l+1)/5 + ((r-l+1)%5==0?0:1);
		int[] b = new int[size];
		int bindex = 0;
		int i = l;
		for (;i < (r-l+1)/5*5 ; i += 5) {
			快速排序.Solution.quicksort(a, i, i+4);
			b[bindex++] = a[i+2];
		}
		if ((r-l+1)%5!=0) {
			快速排序.Solution.quicksort(a, i, r);
			b[bindex] = a[(i+r)/2];
		}
		return findMid(b,0,size-1);
	}
<3>findIndex:返回该中位数在数组中的位置(便于在partion操作中进行交换)
public static int findIndex(int[] a,int num) {
		for (int i = 0 ; i < a.length ; i ++) {
			if (a[i] == num) return i;
		}
		return -1;
	}

<4>partion:将数组分区(小于该中位数的置于前,大于等于该中位数的置于后)
public static int partion(int[] a,int l,int r,int mid,int index) {
		a[l] = a[l] ^ a[index] ^ (a[index] = a[l]);
		int i = l;
		int j = r;
		while (i < j) {
			while (i<j&&a[j]>=mid) j--;
			a[i] = a[j];
			while (i<j&&a[i]<mid) i++;
			a[j] = a[i];
		}
		a[i] = mid;
		return i;
	}
<5>上述代码所求出的是第k大的值,要输出前k大的数只需一次时间复杂度为O(n)的遍历即可。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值