剑指offer编程题解法汇总29-最小的K个数

题目描述

输入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;
                }
            }
        }
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章