题目:在给定的K个数字中找到最大的N个数字?
解析:一、排序,然后找到最大的N个数字,时间复杂度在K的平方到K*logK之间。
二、使用多与空间(数组,map),将最大的K个数字存储起来,时间复杂度K*N。
三、使用map结构的自动排序功能,即将所有的数字放进去,只需要遍历一遍数组,取出最大N个数字时候,使用反向迭代器,时间复杂度N+K,空间复杂度多一个map。
四、使用快排的划分方法,找到最大的N个数字,不在乎最大的N个数字是否排序,时间复杂度K。
第四种解法的方法:使用快排的划分方法,将最后确定的位置返回,如果返回的pos和数组长度差值大于N,则查找pos+1到数组长度,继续划分。反之就查找pos-1到数组左标志位。
void Show(int ar[], int iLen)
{
copy(ar, ar + iLen, ostream_iterator<int>(cout, " "));
cout << endl;
}
int findMaxNumOnce(int ar[], int iLeft, int iRight)
{
int iTmp = ar[iLeft];
//快排的一次划分
while (iLeft < iRight)
{
while (iLeft < iRight && ar[iRight] >= iTmp) iRight--;
if (iLeft < iRight)
ar[iLeft] = ar[iRight];
while (iLeft < iRight && ar[iLeft] <= iTmp) iLeft++;
if (iLeft < iRight)
ar[iRight] = ar[iLeft];
}
ar[iLeft] = iTmp;
return iLeft;
}
int findMaxNum(int ar[], int iLeft, int iRight, int iMaxNum)
{
int iPos = findMaxNumOnce(ar, iLeft, iRight);
cout << iPos << endl;
if (iMaxNum - 1 > iRight - iPos) //找到最大的iMaxNum个数
{
return findMaxNum(ar, iLeft, iPos - 1, iMaxNum-1);
}
else if (iMaxNum - 1 == iRight - iPos)
{
return iPos;
}
else
{
return findMaxNum(ar, iPos+1, iRight, iMaxNum);
}
}
int main()
{
int ar[] = {7,8,45,67,23,33,9,0,8,13,15,55};
int iLen = sizeof(ar) / sizeof(ar[0]);
int iMaxNum = 3;
int iPos = findMaxNum(ar, 0, iLen-1, iMaxNum);
while (iPos < iLen)
{
cout << ar[iPos++] << " ";
}
cout << endl;
return 0;
}