題目描述
輸入n個整數,找出其中最小的K個數。例如輸入4,5,1,6,2,7,3,8這8個數字,則最小的4個數字是1,2,3,4,。
階梯思路:
第一種思路自然是做一個排序,排序完成後取前K個就可以了。但是這應該不是本題的要求。
我的思路是分成兩個數組,一個數組是前K個數,一個數組是後面的數字。先對第一個數組由小到大排序,然後從第二個數組中依次取數,
1.小於第一個數組中最後一個數,則繼續下一個
2.大於第一個數組中最後一個數,則替換掉第一個數組最後一個數,並對該數組進行排序。
import java.util.*;
import java.util.stream.Collectors;
/**
* 最小的K個數
* 輸入n個整數,找出其中最小的K個數。例如輸入4,5,1,6,2,7,3,8這8個數字,則最小的4個數字是1,2,3,4,。
*/
public class Solution {
public static void main(String[] args) {
Solution solution = new Solution();
int[] ints = {4, 5, 1, 6, 2, 7, 3, 8};
ArrayList<Integer> integers = solution.GetLeastNumbers_Solution(ints, 10);
System.out.println(integers);
}
public ArrayList<Integer> GetLeastNumbers_Solution(int[] input, int k) {
ArrayList<Integer> list = new ArrayList<>();
int[] nums = new int[k];
if (k > input.length || k == 0) {
return list;
}
if (k == input.length) {
List<Integer> collect = Arrays.stream(input).boxed().collect(Collectors.toList());
boolean b = list.addAll(collect);
return list;
}
System.arraycopy(input, 0, nums, 0, k);
//前k個數字,歸併排序
maopao(nums);
for (int i = k; i < input.length; i++) {
if (nums[nums.length - 1] > input[i]) {
nums[nums.length - 1] = input[i];
sort(nums);//排序,保證從小到大排序
}
}
List<Integer> integers = Arrays.stream(nums).boxed().collect(Collectors.toList());
list.addAll(integers);
return list;
}
/**
* 0到length-2位是有序的,對ints進行排序
*
* @param ints
*/
private void sort(int[] ints) {
int i = ints.length - 1;
while (true) {
if (i == 0) {
break;
}
if (ints[i] < ints[i - 1]) {
int k = ints[i];
ints[i] = ints[i - 1];
ints[i - 1] = k;
}
i--;
}
}
//本來應該歸併排序,這裏簡單用個冒泡排序吧
private void maopao(int[] ints) {
for (int i = ints.length - 1; i >= 0; i--) {
for (int j = i - 1; j >= 0; j--) {
if (ints[i] < ints[j]) {
int k = ints[i];
ints[i] = ints[j];
ints[j] = k;
}
}
}
}
}