每日一題-2.最小的k個數

題目:

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

實例1:

輸入:arr = [3,2,1], k = 2
輸出:[1,2] 或者 [2,1]

實例2:

輸入:arr = [0,1,2,1], k = 1
輸出:[0]
限制:
0 <= k <= arr.length <= 10000
0 <= arr[i] <= 10000

思考一:

尋找k個最小數,首先建立一個k大小的數組,將原數組的前k個數依次放入到該數組中,繼續循環當前原數組,並且每次找到k大小數組的最大值和當前元素比較,如果發現k數組的最大值大於當前元素,則將k數組元素的最大值替換爲當前元素,遍歷完原數組,則k數組存放的元素則是最小的k個數。
代碼:

class Solution {
    public int[] getLeastNumbers(int[] arr, int k) {
         int result[] = new int[k];
         if(k==0||arr.length==0){
            return new int[0];
         }
         for(int i=0;i < arr.length;i++){
             if(i<k){
                result[i]=arr[i];
             }else{
                 int index = findMaxIndex(result);
                 if(result[index]>arr[i]){
                     result[index]=arr[i];
                 }
             }
         }
         return result;
    }

    public static int findMaxIndex(int arr[]){
         if(arr.length==1){
            return 0;
         }
         int max = 0;
         for(int i=1;i<arr.length;i++){
            if(arr[i]>arr[max]){
                max = i;
            }
         }
         return max;
    }
}

運行實例:

執行用時 :174 ms, 在所有 Java 提交中擊敗了8.09%的用戶
內存消耗 :42.6 MB, 在所有 Java 提交中擊敗了100.00%的用戶

根據提交可以看出,運行效率不是那麼高,考慮下有沒有可以優化的地方。

思考二:

public int[] getLeastNumbers(int[] arr, int k) {
    if (k == 0) {
        return new int[0];
    }
    // 使用一個最大堆(大頂堆)
    // Java 的 PriorityQueue 默認是小頂堆,添加 comparator 參數使其變成最大堆
    Queue<Integer> heap = new PriorityQueue<>(k, (i1, i2) -> Integer.compare(i2, i1));

    for (int e : arr) {
        // 當前數字小於堆頂元素纔會入堆
        if (heap.isEmpty() || heap.size() < k || e < heap.peek()) {
            heap.offer(e);
        }
        if (heap.size() > k) {
            heap.poll(); // 刪除堆頂最大元素
        }
    }

    // 將堆中的元素存入數組
    int[] res = new int[heap.size()];
    int j = 0;
    for (int e : heap) {
        res[j++] = e;
    }
    return res;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章