1、方法一:要求无序数组中没有重复元素,同时允许更改数组内的内容。主要思想是利用快速排序Partition函数依次进行前K个元素的排序,平均时间复杂度O(n)。
#include <iostream>
#include <string>
#include <stack>
#include <fstream>
#include <sstream>
#include <vector>
#include <ctime>
#include <exception>
using namespace std;
void Swap(int *a, int *b)
{
int tmp;
tmp = *a;
*a = *b;
*b = tmp;
}
int Partition(int *arr, int len, int sIdx, int eIdx) //可以返回一个下标,该下标所对应的数组里的数已排序好。
{
if (arr == nullptr || len<=0 || sIdx<0 || eIdx>len-1)
{
cout << "Error occurred in Partition";
return -1;
}
int ii = sIdx, jj = ii+1;
int pivot = arr[sIdx];
for (; jj<=eIdx; ++jj)
{
if (arr[jj]>pivot)
{
Swap(&arr[jj], &arr[++ii]);
}
}
Swap(&arr[ii], &arr[sIdx]);
return ii;
}
void FindKthElem(int *arr, int len, int sIdx, int eIdx, int k)
{
if (arr == nullptr || len<=0 || sIdx<0 || eIdx>len-1 || k<=0 || k>len)
{
cout << "Invalid input.";
return;
}
if (sIdx<=eIdx) //要多加一个等号
{
int midIdx = Partition(arr, len, sIdx, eIdx);
if (midIdx>k-1)
{
FindKthElem(arr, len, sIdx, midIdx, k);
}
else if (midIdx<k-1)
{
FindKthElem(arr, len, midIdx+1, eIdx, k);
}
else
{
cout << endl;
cout << "第" << k << "大的数为:"<< arr[k-1] << endl;
return ;
}
}
}
int main (int argc, char ** argv)
{
int arr[] = {8, 3, 7, 9, 4, 0, 5, 2, 1, 6};
for(int kk=1; kk<=10; ++kk)
{
FindKthElem(arr, 10, 0, 9, kk);
cout << "查找后的数组内元素:";
for (int ii=0; ii<10; ++ii)
cout << arr[ii] << " ";
}
getchar(); getchar();
return 0;
}
2、方法二。使用堆排序。(180412)
vector<int> GetMaxNumbers_Solution(vector<int> input, int k)
{
if (k<=0 || input.size() < k)
return vector<int>();
set<int> output;
for (auto it = input.begin(); it != input.end(); ++it)
{
if (output.size() < k)
{
output.insert(*it);
}
else
{
auto it2 = output.begin();
if (*it > *it2)
{
output.erase(it2);
output.insert(*it);
}
}
}
vector<int> v1(output.begin(), output.end());
return v1;
}
测试结果: