最小的K个数
最大堆
- 时间复杂度 O(n * logk)
- 空间复杂度 O(k)
class Solution {public:vector<int> smallestK(vector<int>& arr, int k) {priority_queue<int, vector<int>, less<int>> que;vector<int> res;for (int n : arr) {que.push(n);if (que.size() > k) que.pop();}while (!que.empty()) {res.push_back(que.top());que.pop();}return res;}};
快排变体
- 不断进行划分
- 如果pivot==k,左边的子数组就是最小的k个数
- 如果pivot<k,继续划分右子数组
- 如果pivot>k,继续划分左子数组
- 时间复杂度 O(n)
- 第一次 n
- 第二次 n/2
- 第三次 n/4
- …
- 相加 < 2n
class Solution {public:vector<int> smallestK(vector<int>& arr, int k) {if (k <= 0) return {};if (arr.size() <= k) return arr;int l = 0, r = arr.size() -1;while (true) {int pivot = partition(arr, l, r);if (pivot == k) break;else if (pivot < k) {l = pivot + 1;} else {r = pivot - 1;}}vector<int> res(arr.begin(), arr.begin()+k);return res;}int partition(vector<int> &arr, int l, int r) {int pivot = l;while (l != r) {while (l < r && arr[r] > arr[pivot]) r--;while (l < r && arr[l] <= arr[pivot]) l++;if (l < r) swap(arr[r], arr[l]);}swap(arr[pivot], arr[l]);return l;}};
- 不断进行划分
