求无序数组中最大的K个数 或 第K大的数

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;
}

测试结果:












猜你喜欢

转载自blog.csdn.net/weixin_38984102/article/details/79586207