【剑指Offer】最小的K个数(partition的应用和堆的应用)

法1:O(n) 要改变数组,partition的思想

 1 class Solution {
 2     public int[] getLeastNumbers(int[] arr, int k) {
 3         int[] ans = new int[k];
 4         findKMin(arr,0,arr.length-1,k);
 5         for(int i = 0; i < k; i++){
 6             ans[i] = arr[i];
 7         }
 8         return ans;
 9     }
10     public void findKMin(int[] arr, int L, int R, int k){
11         if(L < R){
12             int[] p = partition(arr, L, R);
13             if(p[0]+1==k){
14                 return;
15             }
16             findKMin(arr,L,p[0],k);
17             findKMin(arr,p[1],R,k);
18         }
19     }
20     public int[] partition(int[] arr, int L, int R){
21         int less = L-1;
22         int more = R+1;
23         int basic = arr[R];
24         while(L < more){
25             if(arr[L] < basic){
26                 swap(arr,L++,++less);
27             }else if(arr[L] > basic){
28                 swap(arr,L,--more);
29             }else{
30                 L++;
31             }
32         }
33         return new int[]{less,more};
34     }
35     public void swap(int[] arr, int i, int j){
36         int tmp = arr[i];
37         arr[i] = arr[j];
38         arr[j] = tmp;
39     }
40 }

 

法2:O(nlogK)+O(K)适合大数据量且不改变数组,使用堆(自己实现/使用PriorityQueue)

 1 class Solution {
 2     public int[] getLeastNumbers(int[] arr, int k) {
 3         PriorityQueue<Integer> queue = new PriorityQueue<>((o1,o2)->o2-o1);
 4         for(int i = 0; i < arr.length; i++){
 5             queue.add(arr[i]);
 6             if(queue.size() > k){
 7                 queue.poll();
 8             }
 9         }
10         int ans[] = new int[k];
11         for(int i = 0; i < k; i++){
12             ans[i] = queue.poll();
13         }
14         return ans;
15     }
16 }

 

posted @ 2020-06-10 15:11  xd会飞的猫  阅读(160)  评论(0)    收藏  举报