Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element.
For example,
Given
Given
[3,2,1,5,6,4]
and k = 2, return 5.
Note:
You may assume k is always valid, 1 ≤ k ≤ array's length.
You may assume k is always valid, 1 ≤ k ≤ array's length.
Solution:
Method 1: find kth smallest
kth largest number in array nums, is the (nums.length - k + 1)th smallest umber in the array.
And its absolute position in an sorted order is nums.length - k.
Therefore, we recursively call 3-way partition until nums[nums.length - k] is finalized.
Code:
public class Solution { public int findKthLargest(int[] nums, int k) { if (nums == null || nums.length == 0 || k <= 0) { return -1; } k = nums.length - k; int lo = 0; int hi = nums.length - 1; partition(nums, lo, hi, k); return nums[k]; } public void partition(int[] nums, int lo, int hi, int pos) { if (hi <= lo) { return; } int v = nums[lo]; int lt = lo; int gt = hi; int i = lo; while (i <= gt) { if (nums[i] < v) { exch(nums, lt++, i++); } else if (nums[i] > v) { exch(nums, gt--, i); } else { i++; } } if (lt < pos) { partition(nums, lt + 1, hi, pos); } if (lt > pos) { partition(nums, lo, lt - 1, pos); } } public void exch(int[] nums, int i, int j) { int tmp = nums[i]; nums[i] = nums[j]; nums[j] = tmp; } }
Method 2: find kth largest
Modify the 3-way partition to put larger number before pivot and smaller number after pivot.
The kth largest number is nums[k - 1] after partition.
Code:
public class Solution { public int findKthLargest(int[] nums, int k) { if (nums == null || nums.length == 0 || k <= 0) { return -1; } int lo = 0; int hi = nums.length - 1; partition(nums, lo, hi, k - 1); return nums[k - 1]; } public void partition(int[] nums, int lo, int hi, int pos) { if (hi <= lo) { return; } int v = nums[lo]; int gt = lo; int lt = hi; int i = lo; while (i <= lt) { if (nums[i] > v) { exch(nums, gt++, i++); } else if (nums[i] < v) { exch(nums, lt--, i); } else { i++; } } if (gt < pos) { partition(nums, gt + 1, hi, pos); } if (gt > pos) { partition(nums, lo, gt - 1, pos); } } public void exch(int[] nums, int i, int j) { int swap = nums[i]; nums[i] = nums[j]; nums[j] = swap; } }