首页 » 编程之美 » 正文

[编程之美_2.5]寻找最大的k个数

这个问题与寻找第k大/小 数等价。
方法1: 直接排序输出[编程之美书上说:不同的排序方法时间复杂度不一样,诚然,因为不需要n个数有序,只需要最大的k个数即可]
选用快速排序:

vector<</span>int> FindMostKSort(vector<</span>int>& vNumbers, int k)
{
   sort(vNumbers.begin(),vNumbers.end());
   vector<</span>int>vKNumbers(vNumbers.rbegin(), vNumbers.rbegin() + k);
   return vKNumbers;
}

方法2: 实际上并不需要全部数有序,其实可以模拟快速排序的划分过程,求某个数排序之后在第k个位置即可。

void swap(int &a, int &b)
{
   int tmp = a;
   a = b;
   b = tmp;
}
void FindMostKPartition(vector<</span>int>& vNumber, int k, int left, int right)
{
   int index = left;
   int tmp = vNumber[index];
   int i = left;
   int j = right;
   while (i <</span> j)
   {
       while(i <</span> j && vNumber[j] >= vNumber[index])j--;
       swap(vNumber[j], vNumber[index]);
       index = j;
       while(i <</span> j && vNumber[i] <= vNumber[index])i++;
       swap(vNumber[i],vNumber[index]);
       index = i;
   }
   if (index - left + 1 == k)
   {
       cout << vNumber[index] <<endl;
   }
   else
   if (index - left + 1 <</span> k)
   {
       FindMostKPartition(vNumber, k - (index - left + 1), index + 1, right);
   }
   else
   {
       FindMostKPartition(vNumber, k, left, index - 1);
   }
}

方法3: 堆排序[维护一个k数量的最小堆即可,STL代码如此短啊,不过可以自己用数组实现堆]

PS: 排序均用STL实现,具体的排序自己实现,将在近期尝试编写。

void FindMosKHeap(vector<</span>int>& vNumbers, int k)
{
   vector<</span>int> vKNumbers(vNumbers.begin(), vNumbers.begin() + k);
   make_heap(vKNumbers.begin(), vKNumbers.end(), greater<</span>int>());
   for (vector<</span>int>::size_type i = k;i <</span> vNumbers.size();i++)
   {
       if (vNumbers[i] > vKNumbers[0])
       {
           vKNumbers[0] = vNumbers[i];
           make_heap(vKNumbers.begin(), vKNumbers.end(), greater<</span>int>());
       }
   }
   cout << vKNumbers[0] << endl;
}

发表评论