1. 程式人生 > 其它 >劍指offer:JZ29 最小的K個數

劍指offer:JZ29 最小的K個數

技術標籤:劍指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)