题目描述
输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4。
解题思路
方法一:排序
1、思路:直接对数组进行排序,然后返回前K个元素。
2、代码:
class Solution {
public:
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
if (input.empty() || !k || k > input.size()) return vector<int> ();
sort(input.begin(), input.end());
return vector<int> (input.begin(), input.begin() + k);
}
};
3、复杂度:
时间复杂度:O();
空间复杂度:O(1)。
方法二:优先队列
1、思路:开一个长度为K的优先队列,初始化为数组前K个元素,优先队列默认是大顶堆,队列内元素从大到小排序,大元素优先出队,元素在入队的过程中会自动排好序。然后就可以开始遍历数组:
- 若数组当前元素大于优先队列队顶元素,则不做处理,继续遍历数组下一元素;
- 若数组当前元素小于优先队列队顶元素,则该元素入队,队顶元素出队。
遍历完数组所有元素后,优先队列里的K个元素就是数组中最小的K个元素。
2、代码:
class Solution {
public:
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
vector<int> ret (k);
if (input.empty() || !k || k > input.size()) return vector<int> ();
priority_queue<int> result;
int i, count = k;
for (i = 0; i < input.size(); i++) {
if (count > 0) {
result.push(input[i]);
count--;
} else {
if (input[i] < result.top()) {
result.pop();
result.push(input[i]);
}
}
}
for (i = k - 1; i >= 0; i--) {
ret[i] = result.top();
result.pop();
}
return ret;
}
};
3、复杂度:
时间复杂度:O(),对大小为K的堆进行排序需要O(),最坏情况下排序n次;
空间复杂度:O(K)。
方法三:快速排序
1、思路:利用快速排序思想,比较每次划分使用的基准数和第k小元素的关系来求解。
2、代码:
class Solution {
public:
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
if (input.empty() || !k || k > input.size()) return vector<int> ();
return quicksort(input, k, 0, input.size()-1);
}
vector<int> quicksort(vector<int>& input, int k, int l, int r) {
int i = l, j = r;
while (i < j) {
while (i < j && input[j] >= input[l]) j--;
while (i < j && input[i] <= input[l]) i++;
swap(input[i], input[j]);
}
swap(input[i], input[l]);
if (i > k) return quicksort(input, k, l, i-1);
if (i < k) return quicksort(input, k, i+1, r);
vector<int> ret(input.begin(), input.begin()+k);
return ret;
}
};
3、复杂度:
时间复杂度:O(n);
空间复杂度:O()。