leetcode-面试题40-最小的k个数
题目描述:
方法一:快排 O(N) java
class Solution { public int[] getLeastNumbers(int[] arr, int k) { if(k == 0|| arr.length == 0){ return new int[0]; } return quickSerch(arr,0,arr.length -1,k-1); } private int[] quickSerch(int[] nums,int lo,int hi,int k){ int r = partition(nums,lo,hi); if(r == k){ return Arrays.copyOf(nums,r+1); } return r > k? quickSerch(nums,lo,r - 1,k): quickSerch(nums,r+1,hi,k); } private int partition(int[] nums,int lo,int hi){ int pivot = nums[lo]; int l = lo+1,r = hi; while(l <= r){ if (nums[l] > pivot && nums[r] < pivot){ int temp = nums[l]; nums[l] = nums[r]; nums[r] = temp; } if (nums[l] <= pivot) l++; if (nums[r] >= pivot) r--; } nums[lo] = nums[r]; nums[r] = pivot; return r; } }
方法二:大根堆:O(nlogk) 小根堆:O(nlogn)
class Solution { public int[] getLeastNumbers(int[] arr, int k) { if (k == 0 || arr.length == 0){ return new int[0]; } Queue<Integer> pq = new PriorityQueue<>((v1,v2) -> v2 - v1); for (int num:arr){ if (pq.size() < k){ pq.offer(num); }else if(num < pq.peek()){ pq.poll(); pq.offer(num); } } int[] res = new int[pq.size()]; int idx = 0; for(int num:pq){ res[idx++] = num; } return res; } }
方法三:二叉搜索树O(nlogk)
class Solution { public int[] getLeastNumbers(int[] arr, int k) { if (k == 0|| arr.length == 0){ return new int[0]; } TreeMap <Integer,Integer> map = new TreeMap<>(); int cnt = 0; for (int num: arr) { if (cnt < k) { map.put(num, map.getOrDefault(num, 0) + 1); cnt++; continue; } Map.Entry<Integer,Integer> entry = map.lastEntry(); if (entry.getKey() > num){ map.put(num,map.getOrDefault(num,0) + 1); if (entry.getValue() == 1){ map.pollLastEntry(); }else{ map.put(entry.getKey(),entry.getValue() - 1); } } } int [] res = new int[k]; int idx = 0; for (Map.Entry<Integer,Integer> entry:map.entrySet()){ int freq = entry.getValue(); while(freq-- > 0){ res[idx++] = entry.getKey(); } } return res; } }
方法四:计数排序 O(N)
class Solution { public int[] getLeastNumbers(int[] arr, int k) { if (k == 0|| arr.length == 0){ return new int[0]; } int[] counter = new int[10001]; for(int num: arr){ counter[num]++; } int[] res = new int[k]; int idx = 0; for (int num = 0; num < counter.length;num++){ while(counter[num]-- > 0 && idx < k){ res[idx++] = num; } if(idx == k){ break; } } return res; } }