题目描述
给定一个数组,找出其中最小的K个数。例如数组元素是4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4。
0 <= k <= input.length <= 10000
0 <= input[i] <= 10000
方法一:暴力求解
求解思路
最暴力的求解方式,对给出的数组直接进行排序,然后输出前4个数即可
解题代码
class Solution { public: vector<int> GetLeastNumbers_Solution(vector<int> input, int k) { vector<int> myret; if (k==0 || k>input.size()) return myret; // 返回结果 sort(input.begin(), input.end()); // 冒泡排序 return vector<int>({input.begin(), input.begin()+k}); // 返回结果 } };
复杂度分析
时间复杂度:在这里使用的是冒泡排序,平均时间复杂度为
空间复杂度:冒泡排序的空间复杂度,
方法二:优化思路,堆排的思想
求解思路
求解前k个最小的数,我们在暴力解法的基础上,进行改进,使用堆排,让时间复杂度尽可能得低!!!
具体思路:创建一个大根堆,遍历数组的元素,如果堆的大小<k,则入堆,否则与堆顶元素进行比较,如果堆顶元素大,则出堆,将当前元素入堆即可。
解题代码
class Solution { public: vector<int> GetLeastNumbers_Solution(vector<int> input, int k) { vector<int> myres; if (k==0 || k > input.size()) return myres; priority_queue<int, vector<int>> pp; for (const int val : input) { //遍历数组元素 if (pp.size() < k) { pp.push(val); } else { if (val < pp.top()) { //进行比较,如果小,则入堆 pp.pop(); pp.push(val); } } } while (!pp.empty()) // 进行结果的记录 { myres.push_back(pp.top()); pp.pop(); } return myres; // 返回结果即可! } };
复杂度分析
时间复杂度:堆排序的时间复杂度,为,其中k为大根堆的容量。
空间复杂度:创建大根堆,其容量为k,则空间复杂度为