import java.util.*; /** * k largest(or smallest) elements in an array * * Tags: Array, Sort, Heap */ class KthLargest { public static void main(String[] args) { KthLargest K = new KthLargest(); // int[] A = { 1, 3, 5, 2, 4, 6 }; int[] A = {1, 23, 12, 9, 30, 2, 50}; for (int k = 1; k <= A.length; k++) { System.out.println(K.findKthLargest(A, k)); // System.out.println(K.findKthLargestB(A, k)); } } /** * Priority Queue * O(n) + k * O(logn) */ public int findKthLargest(int[] A, int k) { if (k <= 0 || k > A.length) return -1; Queue<Integer> q = new PriorityQueue<Integer>(A.length, Collections.reverseOrder()); for (int n : A) q.add(n); int res = 0; for (int i = 0; i < k; i++) res = q.poll(); return res; } /** * QuickSelect * Use partition algorithm in Quick Sort * Compare partition index with k - 1 * If index > k - 1, means upper bound can be index - 1 * If index < k - 1, means lower bound can be index + 1 * If index == k - 1, return that number */ public int findKthLargestB(int[] A, int k) { if (k <= 0 || k > A.length) return -1; int l = 0; // initialize int r = A.length - 1; int index; while (l < r) { index = partition(A, l, r); if (index > k - 1) { r = index - 1; } else if (index < k - 1) { l = index + 1; } else { return A[index]; } } return A[l]; } /** * Choose mid value as pivot * Move two pointers * Swap and move on * Return left pointer */ private int partition(int[] a, int left, int right) { int pivot = a[left + (right - left) / 2]; while(left <= right) { while(a[left] > pivot) left++; while(a[right] < pivot) right--; if (left <= right) { int temp = a[left]; a[left] = a[right]; a[right] = temp; left++; right--; } } return left; } }