#题目 对于一个数字序列,计算该数字序列第k大数字
##测试样例 输入数据一共有三行。 第一行有一个正整数n(n<=10000000),表示一共给出多少个数字。 第二行有一个正整数k(k<=10000000),表示要求你找出第k大数字。 第三行有n个整数,给出n个数字。对于每个整数i,均满足-10000000<=i<=10000000。
##问题思考 因为要数据比较大,所以要尽可能地减小时间复杂度。
##方法一:哈希线性查找
#include <cstdio>
#include <iostream>
#include <memory.h>
int Ori[20000002]; //open the array in the heap instead of stack
using namespace std;
int main() {
int N,K;
scanf("%d%d",&N,&K);
int count = 1;
bool flag;
memset(Ori, 0, 20000002);
for (int i=0;i<N;i++) {
int num;
scanf("%d",&num);
if (Ori[num+10000000]==0) {
Ori[num+10000000]+=1;
}
}
int j;
for (j = 20000001; j >= 0; j--) {
if (Ori[j]!=0) K--;
if (K==0) {
break;
}
}
printf("%d\n", (j-10000000));
}
##方法二:借助set自动排序,但要注意及时去掉较小的数
#include <cstdio>
#include <iostream>
#include <memory.h>
#include <set>
int array[20000002];
using namespace std;
int main() {
int N,K;
scanf("%d%d",&N,&K);
int count = 1;
bool flag;
set<int> s;
memset(array, 0, 20000002);
for (int i=0;i<N;i++) {
int num;
scanf("%d",&num);
if (array[num+10000000]==0) array[num+10000000]+=1;
}
int i;
for (i = 0; i<20000002; i++) {
if (array[i]!=0) {
s.insert(i-10000000);
if (s.size()>K) {
s.erase(s.begin());
}
}
}
printf("%d\n", (*s.begin()));
}
##方法三:快速选择
#include <cstdio>
#include <iostream>
#include <memory.h>
int array[10000001];
int Ori[20000002];
using namespace std;
int Q_Select(int arr[],int b,int e,int k);
int main() {
int N,K;
scanf("%d%d",&N,&K);
int count = 1;
bool flag;
memset(array, 0, 10000001);
memset(Ori, 0, 20000002);
for (int i=0;i<N;i++) {
int num;
scanf("%d",&num);
if (Ori[num+10000000]==0) {
array[count++]=num;
Ori[num+10000000]+=1;
}
}
printf("%d\n", Q_Select(array, 1, count-1, count-K));
}
int Q_Select(int array[],int start, int end, int k) {
int mid = array[(start+end)/2];
int i = start, j = end;
while (i <= j) {
while (array[i]<mid)
++i;
while (array[j]>mid)
--j;
if (i<=j) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
++i;
--j;
}
}
if (i <= k && i < end) Q_Select(array, i, end, k);
if (j >= k && j > start) Q_Select(array, start, j, k);
return array[k];
}