算法练习-寻找最小的k个数
练习问题来源
https://wizardforcel.gitbooks.io/the-art-of-programming-by-july/content/02.01.html
要求
输入n个整数,输出其中最小的k个
解法
-
最直观的思路,先对 n 个数排序,再一次输出 k 个数,用快速排序,时间复杂度为
O(n*logn)
-
另一种方法,输出的前 k 个最小的数没要求有顺序。可以先取前 k 个数,遍历找到最大的数记 kmax ,再重剩下的
n - k
个数中依次判断是否有< kmax
的数,若有,替换kmax,再重新找 k 个数中最大的记作 kmax ,直至n - k
个数都遍历完。时间复杂度为O(n*k)
// 输入n个整数,输出其中最小的k个
void FindMin_k(int a[], int n, int k)
{
int *b, kmax = a[0], maxIndex = 0;
for (int i = 0; i < k; ++i) // 取 a[] 中的前 k 个数
{
b = a;
++b;
if (kmax < a[i]) // 记录下前 k 个数中最大的数 kmax
{
kmax = a[i];
maxIndex = i;
}
}
b = a;
for (int i = k; i < n; ++i)
{
if (kmax > a[i]) // 后 n-k 个数中若有比 kmax 小的, 与 kmax 替换
*(b + maxIndex) = a[i];
kmax = *b; maxIndex = 0;
for (int j = 0; j < k; ++j) // 重新找 k 个数中最大的
{
if (kmax < *(b + j))
{
kmax = *(b + j);
maxIndex = j;
}
}
}
for (int j = 0; j < k; ++j)
cout << *(b + j) << " ";
cout << endl;
}