O(n)算法得到数组中第k大的数字

在这里插入图片描述
思路:只要牵扯到排序,那么复杂度就是O(nlogn)的了。这里我们借鉴了快速排序的思想,首先任取一个数字,将小于它的放到左边,大于它的放到右边,然后这个数字的位置就可以确定。通过比较k和这个数字的位置,我们就可以判断应该在这个数字的左边还是右边,然后就可以重复上面的操作。最终复杂度是O(n),但是最终数组的位置会改变。
代码如下:

#include<bits/stdc++.h>
#define ll long long
using namespace std;

const int maxx=1e6+100;
int a[maxx];
int n,k;

inline int dfs(int l,int r)
{
	if(l<r)
	{
		int i=l,j=r;
		int x=a[l];
		while(i!=j)
		{
			while(i<j&&a[j]>x) j--;
			while(i<j&&a[i]<=x) i++;
			if(i<j) swap(a[i],a[j]);
		}
		a[l]=a[i];
		a[i]=x;
		return i;
	}
}
inline int find(int len,int num)
{
	int l=0;
	int r=len-1;
	int res=dfs(l,r);
	while(res!=num)
	{
		if(res>num) 
		{
			r=res-1;
			res=dfs(l,r);
		}
		else 
		{
			l=res+1;
			res=dfs(l,r);
		}
	}
	return a[num];
}
int main()
{
	scanf("%d%d",&n,&k);
	for(int i=0;i<n;i++) scanf("%d",&a[i]);
	printf("%d\n",find(n,n-k));
	return 0;
}

努力加油a啊,(o)/~

发布了596 篇原创文章 · 获赞 47 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/starlet_kiss/article/details/105191675