【剑指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 }

浙公网安备 33010602011771号