题目
设计一个算法,找出数组中最小的k个数。以任意顺序返回这k个数均可。
示例:
输入: arr = [1,3,5,7,2,4,6,8], k = 4
输出: [1,2,3,4]
提示:
0 <= len(arr) <= 100000
0 <= k <= min(100000, len(arr))
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/smallest-k-lcci
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
用了快速排序中的快速选择算法。只需要找到一个数,是数组中第 k+1 小的数,就不用继续快速排序了,在它左侧的数即为所求。
时间复杂度:
O
(
n
log
n
)
O(n\log n)
O(nlogn)
空间复杂度:
O
(
1
)
O(1)
O(1)
C++ 代码
class Solution {
public:
vector<int> smallestK(vector<int>& nums, int k) {
if (nums.empty() || k < 1)
return vector<int>();
srand(time(nullptr));
int lo = 0, hi = nums.size() - 1;
int mid = partition(nums, lo, hi);
while (mid != k - 1) {
if (mid > k - 1)
hi = mid - 1;
else
lo = mid + 1;
mid = partition(nums, lo, hi);
}
vector<int> ans(k);
copy(nums.begin(), nums.begin() + k, ans.begin());
return ans;
}
int partition(vector<int>& nums, int lo, int hi) {
if (lo >= hi)
return lo;
swap(nums[lo], nums[lo + rand() % (hi - lo + 1)]);
int pivot = nums[lo];
while (lo < hi) {
while (lo < hi && nums[hi] >= pivot)
--hi;
nums[lo] = nums[hi];
while (lo < hi && nums[lo] < pivot)
++lo;
nums[hi] = nums[lo];
}
nums[lo] = pivot;
return lo;
}
};