K Smallest In Unsorted Array - Medium
Find the K smallest numbers in an unsorted integer array A. The returned numbers should be in ascending order.
Assumptions
- A is not null
- K is >= 0 and smaller than or equal to size of A
Return
- an array with size K containing the K smallest numbers in ascending order
Examples
-
A = {3, 4, 1, 2, 5}, K = 3, the 3 smallest numbers are {1, 2, 3}
M1: min heap
time: O(n + klogn), space: O(1)
public class Solution { public int[] kSmallest(int[] array, int k) { // Write your solution here int[] res = new int[k]; if(array == null || array.length == 0) { return res; } PriorityQueue<Integer> minHeap = new PriorityQueue<>(); for(int n : array) { minHeap.offer(n); } for(int i = 0; i < k; i++) { res[i] = minHeap.poll(); } return res; } }
M2: max heap
time: O(k + (n-k)logk), space: O(1)
public class Solution { public int[] kSmallest(int[] array, int k) { // Write your solution here if(array.length == 0 || k == 0) { return new int[0]; } PriorityQueue<Integer> maxHeap = new PriorityQueue<>(k, new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { if(o1.equals(o2)) { return 0; } return o1 > o2 ? -1 : 1; } }); for(int i = 0; i < array.length; i++) { if(i < k) { maxHeap.offer(array[i]); } else if(array[i] < maxHeap.peek()) { maxHeap.poll(); maxHeap.offer(array[i]); } } int[] res = new int[k]; for(int i = k - 1; i >= 0; i--) { res[i] = maxHeap.poll(); } return res; } }
M3: quick select
time: O(n) worst case O(n^2), space: O(k)
public class Solution { public int[] kSmallest(int[] array, int k) { // Write your solution here if(array.length == 0 || k == 0) { return new int[0]; } quickSelect(array, 0, array.length - 1, k - 1); int[] res = Arrays.copyOf(array, k); Arrays.sort(res); return res; } private void quickSelect(int[] array, int left, int right, int target) { int mid = partition(array, left, right); if(mid == target) { return; } else if(mid < target) { quickSelect(array, mid + 1, right, target); } else { quickSelect(array, left, mid - 1, target); } } private int partition(int[] array, int left, int right) { int pivot = array[right]; int start = left, end = right - 1; while(start <= end) { if(array[start] < pivot) { start++; } else if(array[end] >= pivot) { end--; } else { swap(array, start++, end--); } } swap(array, start, right); return start; } private void swap(int[] array, int i, int j) { int tmp = array[i]; array[i] = array[j]; array[j] = tmp; } }