关键词:分治,快速排序,枢轴
题目
思路
- 方法一:排序后输出。复杂度 O ( n l o g n ) O(nlogn) O(nlogn),不现实。
- 方法二:利用快排的思想,每次选取枢轴,将小于枢轴的放在枢轴左边,大于枢轴的放在右边。然后,枢轴在第几个位置,它就是第几小的数。于是,根据情况选择枢轴、递归其左边、递归其右边。复杂度 O ( n ) O(n) O(n),非常棒。
- 方法三:直接使用STL库里面的
nth_element(array, array+k, array+count)
即可使得array[k]这个元素满足左侧均小于它且右侧均大于它。
代码
#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#define condition(_c,_t,_f) ((_c)?(_t):(_f))
#define abs(x) condition((x)>=0,(x),-(x))
#define min(x,y) condition((x)<(y),x,y)
#define max(x,y) condition((x)>(y),x,y)
using namespace std;
int a[6000000];
inline void swap(int* i1, int* i2){
int temp=*i1;
*i1=*i2;
*i2=temp;
}
inline int search(int *start, int nth, int count){
int pivot = start[0];
int *l=start,*r=start+count-1;
bool rmove = true;
while(l<r){
if(rmove){
if(*r<pivot) {
swap(l,r);
rmove = false;
}
else r--;
}
else{
if(*l>pivot) {
swap(l,r);
rmove = true;
}
else l++;
}
}
int c = l-start;
if(c>nth) return search(start,nth,c);
if(c==nth) return *l;
if(c<nth) return search(l+1,nth-c-1,count-c-1);
}
int main(){
int n, k;
scanf("%d %d",&n,&k);
for(int i=0;i<n;i++)scanf("%d",a+i);
// 方法二:
//printf("%d",search(a,k,n));
// 方法三:
nth_element(a,a+k,a+n);
printf("%d",a[k]);
}