題目:
輸入整數數組 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;
}