题目描述
输入整数数组 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
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/zui-xiao-de-kge-shu-lcof
算法步骤
- 采用快排的思路,选取
arr
的最后一位为主元pivot
,将数组分割成为小于pivot
和大于pivot
两部分,并将pivot
放到其对应下标,记录pivot
的下标index
; - 若
index == k
,则直接返回arr
的前(k)位。 - 若
index > k
,则对前半部分的数组进行划分,否则对后半部分数组进行划分,直至index == k
。
代码实现
class Solution {
private:
int partition(vector<int>& arr, int left, int right) {
int pivot = arr[right];
int i = left;
for(int j = left; j < right; j++) {
if(arr[j] < pivot) {
swap(arr[i++], arr[j]);
}
}
swap(arr[i], arr[right]);
return i;
}
public:
vector<int> getLeastNumbers(vector<int>& arr, int k) {
if(k == arr.size())
return arr;
int left = 0;
int right = arr.size() - 1;
int order_index = partition(arr, left, right);
while(order_index != k) {
if(order_index < k)
left = order_index + 1;
else
right = order_index - 1;
order_index = partition(arr, left, right);
}
vector<int> result;
for(int i = 0; i < order_index; i++)
result.push_back(arr[i]);
return result;
}
};