题目描述
输入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;
}
}
}
}
}