思想:
一.先排序,在输出后m个元素。(复杂度O(nlogn))
一.先排序,在输出后m个元素。(复杂度O(nlogn))
二.先把前m大的元素弄到数组最右边,在对这m个数进行排序(复杂度为O(n+mlogm),其中
把前m大的元素弄到数组最右边花费为O(n))
如何把前m大的元素弄到数组最右边?
1.以a[0]为枢轴,把比他大的放在其后,比它小的放在其前。记录它比他大的元素个数(包括自己)为cnt
若cnt==m,函数结束
cnt<m,对枢轴左边的元素进行arrange(m-cnt)
cnt>m,对枢轴右边的元素进行arrange(m)
#include <cstdio>
#include <iostream>
#include <algorithm>
#define N 100005
using namespace std;
int a[N];
void arrange(int a[], int s, int e, int m)
{
if (s >= e)
return;
int pivot = a[s];
int i = s, j = e;
while (i < j)
{
while (i < j && a[j] >= pivot)
j--;
swap(a[i], a[j]);
while (i < j && a[i] <= pivot)
i++;
swap(a[i], a[j]);
}
int cnt = e - i + 1;
if (cnt == m)
return;
else if (cnt > m)
arrange(a, i + 1, e, m);
else
arrange(a, s, i - 1, m - cnt);
}
int main()
{
int n,m;
scanf("%d", &n);
for (int i = 0; i < n; i++)
scanf("%d", &a[i]);
scanf("%d", &m);
arrange(a, 0, n - 1, m);
sort(a + n - m, a + n);
for (int i = n - 1; i > n - m -1; i--)
printf("%d\n", a[i]);
return 0;
}