快速选择算法(求解第k大)

Posted Harris-H

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了快速选择算法(求解第k大)相关的知识,希望对你有一定的参考价值。

快速选择算法(求解第k大)

​ 快速选择算法基于快排。

​ 复习一波快排:

void quick_sort(int l,int r){
	if(l<r){
	int i=l,j=r,x=a[l];//x是基数. 
	while(i<j){
		while(i<j&&a[j]>x) j--;	//从右往左找到第一个小于等于x的 
		if(i<j) a[i++]=a[j];//填到左边i 
		while(i<j&&a[i]<x) i++;//从左往右找到第一个大于等于x的 
		if(i<j) a[j--]=a[i];//填到右边j 
	}a[i]=x;
	quick_sort(l,i-1);//递归 
	quick_sort(i+1,r);
	}
} 
  • 选择一个基数
  • 把比该基数小的放到左边,大的放到右边。
  • 递归左、右部分。

因此我们只需要知道第 k k k大是多少,我们并不关心它的左、右部分是否有序。

所以基于快排,我们可以对时间复杂度进行优化。

  • 每次随机选择一个基数,这里用随机的原因,如果每次选最大或者最小的话,时间复杂度最坏会达到 O ( n 2 ) O(n^2) O(n2)
  • 然后把该基数交换到最右部分。
  • 遍历 [ l , r ) [l,r) [l,r),用两个指针 i , j i,j i,j,开始都指向 l l l
    • 若当前 a [ j ] ≤ x a[j]\\le x a[j]x,就交换 ( a [ i ] , a [ j ] ) (a[i],a[j]) (a[i],a[j]),然后两个指针都向右移动一位。
    • 否则, j j j指针向右移动一位。
  • 当遍历完之后,交换 a [ i ] , a [ r ] a[i],a[r] a[i],a[r],此时 i i i左边的元素都小于等于它,右边的都大于它。
  • 然后返回位置 i i i,即该元素是第 i i i小的。
    • 若该位置 i i i是我们要找到第 i i i小,则直接返回。
    • 否则若 i < p o s i<pos i<pos,则往右递归,否则往左递归。
  • 这样每次只用递归一个部分,不用像快排那样递归两个部分。

时间复杂度: O ( n ) O(n) O(n)

事实上 S T L STL STL已经帮我们实现了 ( v o i d )   n t h _ e l e m e n t ( s t a r t , p o s , e n d ) (void)\\ nth\\_element(start,pos,end) (void) nth_element(start,pos,end)

nth_element(a.begin(),a.begin()+k-1,a.end()) 
return a[k-1]; //第k小

nth_element(a.begin(),a.begin()+k-1,a.end(),greater<int>())
return a[k-1]; //第k大

自己实现第 k k k大。

int partition(vector<int>&a,int l,int r){
	int i = rand()%(r-l+1)+l;
	swap(a[i],a[r]);
	int x=a[r];i=l;
	for(int j=l;j<r;j++){
		if(a[j]<=x){
			swap(a[i++],a[j]);
		}
	}
	swap(a[i],a[r]);
	return i;
    }
    int nth(vector<int>&a,int l,int r,int p){
        int q=partition(a,l,r);
        if(q==p) return a[q];
        else return q<p?nth(a,q+1,r,p):nth(a,l,q-1,p);
    }
	int solve(vector<int> &a,int k){
        srand(time(0));
        return nth(a, 0, a.size() - 1, a.size() - k);
    }

以上是关于快速选择算法(求解第k大)的主要内容,如果未能解决你的问题,请参考以下文章

Leetcode题解——算法思想之排序

随机选择第k小元素随机快速排序-算法设计与分析实验四

随机选择第k小元素随机快速排序-算法设计与分析实验四

随机选择第k小元素随机快速排序-算法设计与分析实验四

算法快速选择算法 ( 数组中找第 K 大元素 )

快速选择算法的实现以找到第k个最小的数字