第K小的数字

题目:给定无序序列,要求输出第k小的数字

tip1:排序完直接选第k小的数字 O(nlog(n))

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main() {
	int n,k;
	cin>>n>>k;
	int b[n];
	for(int i=0; i<n; ++i)
		cin>>b[i];
	sort(b,b+n);
	cout<<b[k-1];
}

tip2:用堆的思想 O(nlog(n))

#include<iostream>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
int main() {
	int n,k;
	cin>>n>>k;
	priority_queue<int,vector<int>,greater<int>> q;
	for(int i=0; i<n; ++i) {
		int  t;
		cin>>t;
		q.push(t);
	}
	while(--k)
		q.pop();
	cout<<q.top();
}

tip3:从序列中选取一个数当作mid,然后将序列按小于等于和大于等于mid分为两部分,根据第一部分的元素个数决定第k小的数字在前半段部分还是后半段部分,然后分情况讨论递归左右子区间。O(n)

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
vector<int>a;
void quick_select(int l,int r,int k) {
	int i=l,j=r,mid=(l+r)/2;
	do {//分类
		while(a[i]<a[mid])++i;
		while(a[j]>a[mid])--j;
		if(i<=j) {
			swap(a[i],a[j]);
			++i;
			--j;
		}
	} while(i<=j);
	if(j>=l&&k<j-l+1)//所在区间讨论
		quick_select(l,j,k);
	else if(i<=r&&k>i-l+1)
		quick_select(i,r,k-(i-l));
}
int numK(int l,int r,int k) {
	quick_select(l,r,k);
	return a[k-1];
}
int main() {
	int n,k;
	cin>>n>>k;
	a.resize(n);
	for(int i=0; i<n; ++i)
		cin>>a[i];
	cout<<numK(0,n-1,k);
	return 0;
}
发布了382 篇原创文章 · 获赞 17 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_40991687/article/details/104240294