数据结构与算法面试题查找最小的k个数
Posted zhiyong_will
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构与算法面试题查找最小的k个数相关的知识,希望对你有一定的参考价值。
题目来源“数据结构与算法面试题80道”。
问题分析:这是一道比较经典的题目,查找最小的k个元素,最简单的方法就是对这n个整数排序,排序完成后,直接输出前k个最小的元素。那么最快的排序方法是快速排序,其算法的时间复杂度为O(nlogn)。是否还存在比这个更快的方法呢?
方法一:利用快速排序的思想,时间复杂度为O(n)
按照某个点将数组划分成左右两部分,左边的数都小于该划分节点,右边的数都大于该划分节点。如果最终该划分节点的位置小于k-1,则在右边节点中继续划分;如果最终该划分节点的位置大于k-1,则在左边节点中继续划分。这个过程直到最终的划分节点的位置正好为k-1。
int swap(int *a, int start, int end, int point_index)
int par_point = a[point_index];
while (start < end)
if (a[start] >= par_point && a[end] <= par_point)
int tmp = a[start];
a[start] = a[end];
a[end] = tmp;
start ++;
end --;
else if(a[start] < par_point)
start ++;
else
end --;
return start;
void get_min_k(int *a, int length, int k)
if (k > length || NULL == a || length <= 0) return;
int new_index = swap(a, 0, length-1, k);
while (true)
if (new_index == k) break;
else if (new_index > k)
new_index = swap(a, 0, new_index, k);
else
new_index = swap(a, new_index, length-1, k);
方法二:利用堆排序,时间复杂度为O(nlogk)
上述方法的缺点是其对数组进行了修改,在堆排序中,可采用小顶堆,其中堆的大小为k,若此时堆的大小小于k时,则将数插入堆中;若此时堆中的大小大于等于k,则比较堆中最大的整数与待插入整数的大小,插入较小的整数。
void get_min_k(int *a, int length, int k, set<int> &s)
if (k > length || NULL == a || length <= 0) return;
for (int i = 0; i < length; i++)
if (s.size() < k)
s.insert(a[i]);
else
set<int>::iterator it = --s.end();
if (a[i] < *it)
s.erase(*it);
s.insert(a[i]);
以上是关于数据结构与算法面试题查找最小的k个数的主要内容,如果未能解决你的问题,请参考以下文章
堆的相关习题 面试题17.14最小的K个数 347前K个高频元素 373查找和最小的K对数字