求中位数容易想到的方法就是排序,直接去n/2大,但这样排序时间就需要O(nlogn),总体时间也就是O(nlogn)。
有时候并不能满足我们需要随机存取第k大元素要求。
所以就有了线性求中位数的方法。
第一种方法:nth_element
#include<cstdio>
#include<cmath>
#include<cstring>
#include<string>
#include<cstdlib>
#include<algorithm>
#include<iostream>
#include<queue>
#include<stack>
#include<map>
using namespace std;
#define FOU(i,x,y) for(int i=x;i<=y;i++)
#define FOD(i,x,y) for(int i=x;i>=y;i--)
#define MEM(a,val) memset(a,val,sizeof(a))
#define PI acos(-1.0)
const double EXP = 1e-9;
typedef long long ll;
typedef unsigned long long ull;
const int INF = 0x3f3f3f3f;
const ll MINF = 0x3f3f3f3f3f3f3f3f;
const double DINF = 0xffffffffffff;
const int mod = 1e9+7;
const int N = 1e6+5;
int a[N];
int main()
{
//freopen("xor_equ.in","r",stdin);
//freopen("xor_equ.out","w",stdout);
std::ios::sync_with_stdio(false);
int n;
while(~scanf("%d",&n)){
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
ll ans=0;
int k = n/2+1;
nth_element(a+1,a+k,a+1+n);
ans+=a[k];
if(n%2==0){ //偶数需要多加一个
k--;
nth_element(a+1,a+k,a+1+n);
ans+=a[k];
ans = floor(ans*0.5);
}
printf("%lld\n",ans);
}
return 0;
}
第二种:快排思想,分组
#include<cstdio>
#include<cmath>
#include<cstring>
#include<string>
#include<cstdlib>
#include<algorithm>
#include<iostream>
#include<queue>
#include<stack>
#include<map>
using namespace std;
#define FOU(i,x,y) for(int i=x;i<=y;i++)
#define FOD(i,x,y) for(int i=x;i>=y;i--)
#define MEM(a,val) memset(a,val,sizeof(a))
#define PI acos(-1.0)
const double EXP = 1e-9;
typedef long long ll;
typedef unsigned long long ull;
const int INF = 0x3f3f3f3f;
const ll MINF = 0x3f3f3f3f3f3f3f3f;
const double DINF = 0xffffffffffff;
const int mod = 1e9+7;
const int N = 1e6+5;
int a[N];
int find_mid(int *a,int left,int right,int k){
if(left>=right){
return a[left+k-1];
}
int key = a[left];
int i=left,j=right;
while(i<j){
while(i<j&&a[j]>=key) j--;
swap(a[i],a[j]);
while(i<j&&a[i]<=key) i++;
swap(a[i],a[j]);
}
a[i]=key;
if(i-left+1==k)
return a[i];
else if(i-left+1<k)
return find_mid(a,i+1,right,k-(i-left+1));
else
return find_mid(a,left,i-1,k);
}
int main()
{
int n;
while(~scanf("%d",&n)){
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
ll ans=0;
if(n%2)
ans = find_mid(a,1,n,n/2+1);
else{
ans += find_mid(a,1,n,n/2);
ans += find_mid(a,1,n,n/2+1);
ans>>=1;
}
printf("%lld\n",ans);
}
return 0;
}