您的位置:首页 > 其它

[HDU] 1157 Who's in the Middle - 不排序查找第x小的元素,时间复杂度接近o(n)

2013-04-23 13:59 429 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1157

方法:通过像快速排序那样进行一个划分,划分只对一个部分进行处理而不是像快速排序那样对两个都处理。当随机选择一个元素进行了划分后,开划分的位子k在哪里,如果把x-th元素的x等于k,则直接返回,小于,就在前面一个部分递归下去找地x-th小的元素, 否则,x-=k,在后面一个部分去找。在该题目中x为n/2+1.

感谢:时间复杂度接近o(n),这是根据概率分布计算出来的,以后要学会其证明,包括快速排序的证明。

代码:

View Code

#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;
int n;
int numbers[10001];
int getRandomNumber(int st,int ed)
{
srand((unsigned)time(NULL));
return (rand()%(ed-st+1))+st;
}
int partion(int st,int ed)
{
int i =st-1;
int j=st;
int r = ed;
for(j=st;j<r;j++)
{
if(numbers[j]<=numbers[r])
{
i++;
int temp = numbers[j];
numbers[j] = numbers[i];
numbers[i] = temp;
}
}
int temp = numbers[r];
numbers[r] = numbers[i+1];
numbers[i+1] = temp;
return i+1;
}
int randonPartion(int st,int ed)
{

int p = getRandomNumber(st,ed);
int temp = numbers[p];
numbers[p] = numbers[ed];
numbers[ed]=temp;
return partion(st,ed);
}
int getTarget(int x,int st = 1,int ed=n)
{
int p= randonPartion(st,ed);
int k = p-st+1;
if(k==x)
return numbers[st+k-1];
else
{
if(x>k)
return getTarget(x-k,p+1,ed);
else
return getTarget(x,st,p-1);
}
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
for(int i = 1;i<=n;i++)
scanf("%d",&numbers[i]);
cout<<getTarget(n/2+1)<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: