leetcode 面试题40. 最小的k个数
题目详情
题目链接
输入整数数组 arr ,找出其中最小的 k 个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。
- 示例 1:
输入:arr = [3,2,1], k = 2
输出:[1,2] 或者 [2,1]- 示例 2:
输入:arr = [0,1,2,1], k = 1
输出:[0]- 限制:
0 <= k <= arr.length <= 10000
0 <= arr[i] <= 10000
我的代码
class Solution {
public:
vector<int> getLeastNumbers(vector<int>& arr, int k) {
vector<int> res;
for (int n = 0; n < k; ++n) {
int temp = arr[n];
int loc = n;
for (int i = n + 1; i < arr.size(); ++i) {
if (arr[i] < temp) {
temp = arr[i];
loc = i;
}
}
res.push_back(temp);
swap(arr[n], arr[loc]);
}
return res;
}
};
我的成绩
执行结果:通过
执行用时 : 680 ms, 在所有 C++ 提交中击败了6.33%的用户
内存消耗 : 20.3 MB, 在所有 C++ 提交中击败了100.00%的用户
一些想法
- 本道题我用的比较暴力的手段,即找到数组中前k小的元素进行返回。
执行用时为 8 ms 的范例
class Solution {
public:
void swap(int& x, int& y) {
int tem = x;
x = y;
y = tem;
}
void adjustHeap(vector<int>& heap, int index) {
for(int i = index; i * 2 + 1 < heap.size();) {
int tem = i * 2 + 1;
if(i * 2 + 2 < heap.size() && heap[i * 2 + 2] > heap[i * 2 + 1])
tem = i * 2 + 2;
if(heap[tem] <= heap[i])
break;
swap(heap[tem], heap[i]);
i = tem;
}
}
void buildHeap(vector<int>& heap) {
for(int i = heap.size() / 2 - 1; i >= 0; --i) {
adjustHeap(heap, i);
}
}
vector<int> getLeastNumbers(vector<int>& arr, int k) {
if(k == 0)
return vector<int>(0);
vector<int> kheap(arr.begin(), arr.begin() + k);
buildHeap(kheap);
for(int i = k; i < arr.size(); ++i) {
if(arr[i] >= kheap[0])
continue;
kheap[0] = arr[i];
adjustHeap(kheap, 0);
}
return kheap;
}
};
思考
- 范例使用了堆。可参考官方解答