劍指offer:JZ29 最小的K個數
阿新 • • 發佈:2020-12-09
技術標籤:劍指offer
題目描述
輸入n個整數,找出其中最小的K個數。例如輸入4,5,1,6,2,7,3,8這8個數字,則最小的4個數字是1,2,3,4。
示例1
輸入
[4,5,1,6,2,7,3,8],4
返回值
[1,2,3,4]
線上連結
程式碼:
import java.util.*;
public class Solution {
ArrayList<Integer> list = new ArrayList<>();
public ArrayList<Integer> GetLeastNumbers_Solution (int[] input, int k) {
if (input.length < k || k <= 0) {
return list;
}
partition(input, 0, input.length - 1, k - 1);
return list;
}
private void partition(int[] nums, int l, int r, int k) {
swap(nums, l, (int) (l + (r - l + 1) * Math. random()));
int less = l - 1;
int more = r;
int left = l;
while (l < more) {
if (nums[l] < nums[r]) {
swap(nums, ++less, l++);
} else if (nums[l] > nums[r]) {
swap(nums, l, --more);
} else {
l++ ;
}
}
swap(nums, r, more);
if (l == k) {
for (int i = 0; i <= l; i++) {
list.add(nums[i]);
}
} else if (l > k) {
partition(nums, left, l - 1, k);
} else {
partition(nums, l + 1, r, k);
}
}
private void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
思路概述:
這是一個topK問題,只不過不是輸出第K大的數,而是輸出最小的K個數,思路不變,同樣裡利用快排的特性。我們知道,每進行一次快排,我們可以確定一個元素(如果有相同元素,那就是這一組相同元素)的位置
比如說,紅色的元素是排好的元素,我們可以確定,前面兩個元素肯定是最小的兩個,後面三個是最大的三個。所以我們利用快排的特性來做這個題。
比如一次遍歷後是這樣的情況,如果l == k-1,代表已經找到最小的k個數了,直接儲存即可
如果l > k-1,代表多了,那我們只需要排前半部分即可(left – l-1)
如果l < k- 1,代表數量不夠,那我們只需要排後半部分即可(l + 1 — r)