快速排序—求第k大的数O(n)版
Description
FJ is surveying his herd to find the most average cow. He wants to know how much milk this 'median' cow gives: half of the cows give as much or more than the median; half give as much or less.
Given an odd number of cows N (1 <= N < 10,000) and their milk output (1..1,000,000), find the median amount of milk given such that at least half the cows give the same amount of milk or more and at least half give the same or less.
Input
- Line 1: A single integer N
- Lines 2..N+1: Each line contains a single integer that is the milk output of one cow.
Output
- Line 1: A single integer that is the median milk output.
Sample Input
5
2
4
1
3
5
Sample Output
3
More Info
INPUT DETAILS:
Five cows with milk outputs of 1..5
OUTPUT DETAILS:
1 and 2 are below 3; 4 and 5 are above 3.
分析
这道题是去求中间大的数,也是一道第k大的数的模板题,如果我们用sort进行排序后,在定位k大的数,那么时间复杂度就是O(nlog2n);
我们自写快排的时候,每次划分只需要保留包含第k个数的那部分就ok了,复杂度就是O(n) + O(n/2) + O(n/4) + O(n/8) + ... + O(1)为O(n)。
代码实现
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 10010;
int a[N]; //存数据
int quicksort(int left, int right, int k){
int mid = a[left + (right - left) / 2];
int i = left, j = right - 1;
while(i <= j){
while(a[i] < mid) ++i;
while(a[j] > mid) --j;
if(i <= j){
swap(a[i], a[j]);
++i;--j;
}
}
if(left <= j && k <= j) return quicksort(left, j + 1, k);
if(i < right && k >= i) return quicksort(i, right, k);
return a[k]; //返回第k大数
}
int main(){
int n; scanf("%d", &n);
for(int i = 0; i < n; i++) scanf("%d", &a[i]);
int k = n/2;
printf("%d\n", quicksort(0, n, k));
return 0;
}

浙公网安备 33010602011771号