劍指 Offer 40. 最小的k個數(java實現)--LeetCode
阿新 • • 發佈:2021-02-05
技術標籤:堆演算法題演算法題資料結構javaleetcode
文章目錄
題目:
輸入整數陣列 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
解法1:排序
/**
* 思路:
* 排序陣列,獲取k個值
*/
public int[] getLeastNumbers(int[] arr, int k) {
int[] result=new int[k];
//nlogn
Arrays.sort(arr);
for (int i=0;i<k;i++){
result[i]=arr[i];
}
return result;
}
時間複雜度:Onlogn
空間複雜度:On
解法2:新建陣列
/**
* 思路:
* 在有限資料的情況下
* 建立一個大的陣列,存放arr陣列中的所有資料,把這些資料的值作為索引,出現的次數作為值
*/
public int[] getLeastNumbers(int[] arr, int k) {
int[] result=new int[k];
int index=0;
int[] count = new int[10000];
for (int i:arr){
count[i]++;
}
for (int i=0;i<count.length;i++){
while (count[i]>0){
if (index== k)return result;
result[index++]=i;
count[i]--;
}
}
return result;
}
時間複雜度:On^2
空間複雜度:On
解法3:heap(小頂堆)
/**
* 思路:
* 小頂堆實現
* heap,把陣列元素放入堆,獲取堆頂元素k次
*/
public int[] getLeastNumbers(int[] arr, int k) {
int[] result=new int[k];
PriorityQueue<Integer> heap = new PriorityQueue<>();
//插入操作logn,整體nlogn
for (int i:arr)heap.add(i);
for (int i=0;i<k;i++)result[i]=heap.remove();
return result;
}
時間複雜度:Onlogn
空間複雜度:On
解法4:大頂堆
/**
* 思路:
* 大頂堆實現
* 把前k個元素放入堆,後續的元素如果比堆頂元素小,移除堆頂元素,加入新元素
*/
public int[] getLeastNumbers(int[] arr, int k) {
int[] result=new int[k];
if (k==0)return result;
PriorityQueue<Integer> heap = new PriorityQueue<>((v1,v2)->v2-v1);
for (int i=0;i<arr.length;i++){
if (i<k)heap.add(arr[i]);
else {
if (heap.peek()>arr[i]){
heap.remove();
heap.add(arr[i]);
}
}
}
int i=0;
for (int num : heap)result[i++]=num;
// for (int i=0;i<k;i++)result[i]=heap.remove();
return result;
}
時間複雜度:Onlogn
空間複雜度:On