劍指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;
                }
            }
        }
    }
}

 

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