題目:給定無序序列,要求輸出第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;
}