劍指Offer—— 最小的K個數

題目描述

輸入n個整數,找出其中最小的K個數。例如輸入4,5,1,6,2,7,3,8這8個數字,則最小的4個數字是1,2,3,4


第一種方法是全排序,先把數組進行排序,排序後依次輸出最小的4個,時間複雜度爲nlogn。

第二種方法是的原理和快速排序有關,是通過快速排序的優化版解題目。快速排序是定義一個基點(一般是第一個數字),每次排序後會把數組中小於基點的放在前面,大於基點的放在後面。(具體的快速排序算法不說了)

如題目中的一個基點爲4,第一次排序後:3, 2, 1, 4, 6, 7, 5, 8。如果我們需要的k和4的位置相等,就不用繼續排序,因爲4之前的都是小於4的。k比4所在的位置大時,只需要排序4之後的數字。k比4所在的位置小時,只需要排序4之前的數字。
(掌握快速排序應該對這個思路很瞭解,這個最糟糕的情況是nlogn)

public class Solution13 {
    public ArrayList<Integer> GetLeastNumbers_Solution(int[] input, int k) {
        ArrayList<Integer> list=new ArrayList<>();
        if(input.length<k) return list;
        quicksort(input,0,input.length-1,list,k);
        for(int i=0;i<k;i++){
            list.add(input[i]);
        }
        return list;
    }
    //類似快速排序
    private void quicksort(int[] input, int s, int end, ArrayList<Integer> list,int k) {
        if(s>end) return ;
        if(s==end){
            return ;
        }
        int temp=input[s];
        int i=s,e=end;
        //快速排序
        while(i<e){
            while(e>i&&temp<=input[e]){
                e--;
            }
            input[i++]=input[e];
            while(e>i&&temp>=input[i]){
                i++;
            }
            input[e]=input[i];
        }
        input[e]=temp;
        //如果k==e,說明e之前的都是小於e的,k〉e還需要排序後面的,e〉k要排序前面的
        if(e==k)
            return;
        else if(e<k){
            quicksort(input, e+1, end, list, k);
        }else{
            quicksort(input, s, e-1, list, k);
        }
    }

    public static void main(String[] args) {
        int[] a={4,5,1,6,2,7,3,8};
        Solution13 b = new Solution13();
        System.out.println(b.GetLeastNumbers_Solution(a,4));
    }
}
發佈了97 篇原創文章 · 獲贊 19 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章