力扣原题
Design an algorithm to find the smallest K numbers in an array.
Example:
Input: arr = [1,3,5,7,2,4,6,8], k = 4
Output: [1,2,3,4]
Note:
0 <= len(arr) <= 1000000 <= k <= min(100000, len(arr))典型的前K个最大,最小值问题;
来算一下时间复杂度,建堆
O
(
n
)
O(n)
O(n),出堆
O
(
l
o
g
n
)
O(logn)
O(logn) ,一共出堆
k
k
k 次。
总的时间复杂度是:
O
(
n
+
k
l
o
g
n
)
O(n + klogn)
O(n+klogn)
空间复杂度(建堆)是:
O
(
n
)
O(n)
O(n)
能不能直接降到
O
(
n
)
O(n)
O(n)啊?
每一次快排之后的基准(哨兵) p i v o t pivot pivot 的下标为 i n d e x index index,则左边都是比它小的,一共有 i n d e x index index个,右边都是比它大的。
fast_sort(arr, k, start, left - 1)fast_sort(arr, k, ledt + 1, end)class Solution {
public:
vector<int> ans;
void fast_sort(vector<int> &arr, int k, int start, int end) {
int left = start, right = end;
while (left < right) {
// 如果标记在右边, 那第一个 while 就先从左到右
// 否则从右到左
while (left < right && arr[left] <= arr[end]) left++;
while (left < right && arr[right] >= arr[end]) right--;
swap(arr[left], arr[right]);
}
swap(arr[left], arr[end]);
if (left < k) fast_sort(arr, k, left + 1, end);
if (left > k) fast_sort(arr, k, start, left - 1);
ans.assign(arr.begin(), arr.begin() + k);
}
vector<int> smallestK(vector<int>& arr, int k) {
// 如果有的题目 k > n 就做下面这个判断
// if (k >= arr.size()) return arr;
fast_sort(arr, k, 0, arr.size() - 1);
return ans;
}
};
就是加了两个判断。