|
| 1 | +# Kth Largest Element in an Array |
| 2 | + |
| 3 | +Tags: Quick Sort, Divide and Conquer, Medium |
| 4 | + |
| 5 | +## Question |
| 6 | + |
| 7 | +- leetcode: [(215) Kth Largest Element in an Array](https://leetcode.com/problems/kth-largest-element-in-an-array/) |
| 8 | +- lintcode: [(5) Kth Largest Element](http://www.lintcode.com/en/problem/kth-largest-element/) |
| 9 | + |
| 10 | +### Problem Statement |
| 11 | + |
| 12 | +Find the **k**th largest element in an unsorted array. Note that it is the kth |
| 13 | +largest element in the sorted order, not the kth distinct element. |
| 14 | + |
| 15 | +For example, |
| 16 | +Given `[3,2,1,5,6,4]` and k = 2, return 5. |
| 17 | + |
| 18 | +**Note: ** |
| 19 | +You may assume k is always valid, 1 ≤ k ≤ array's length. |
| 20 | + |
| 21 | +**Credits:** |
| 22 | + |
| 23 | +Special thanks to [@mithmatt](https://leetcode.com/discuss/user/mithmatt) for |
| 24 | +adding this problem and creating all test cases. |
| 25 | + |
| 26 | +## Solution |
| 27 | + |
| 28 | +Trail and error: Comparison-based sorting algorithms don't work because they incur ***O(n2)*** time complexity. Neither does Radix Sort which requires the elements to be in a certain range. In fact, Quick Sort is the answer to `kth largest` problems ([Here](http://algorithm.yuanbin.me/zh-hans/basics_sorting/quick_sort.html) are code templates of quick sort). |
| 29 | + |
| 30 | +By quick sorting, we get the final index of a pivot. And by comparing that index with `K`, we decide which side (the greater or the smaller) of the pivot to recurse on. |
| 31 | + |
| 32 | +### Java |
| 33 | + |
| 34 | +```java |
| 35 | +public class Solution { |
| 36 | + public int findKthLargest(int[] nums, int k) { |
| 37 | + if (nums == null || nums.length == 0) { |
| 38 | + return Integer.MIN_VALUE; |
| 39 | + } |
| 40 | + |
| 41 | + int kthLargest = qSort(nums, 0, nums.length - 1, k); |
| 42 | + return kthLargest; |
| 43 | + } |
| 44 | + |
| 45 | + private int qSort(int[] nums, int left, int right, int k) { |
| 46 | + if (left >= right) { |
| 47 | + return nums[right]; |
| 48 | + } |
| 49 | + |
| 50 | + int m = left; |
| 51 | + for (int i = left + 1; i <= right; i++) { |
| 52 | + if (nums[i] > nums[left]) { |
| 53 | + m++; |
| 54 | + swap(nums, m, i); |
| 55 | + } |
| 56 | + } |
| 57 | + swap(nums, m, left); |
| 58 | + |
| 59 | + if (k == m + 1) { |
| 60 | + return nums[m]; |
| 61 | + } else if (k > m + 1) { |
| 62 | + return qSort(nums, m + 1, right, k); |
| 63 | + } else { |
| 64 | + return qSort(nums, left, m - 1, k); |
| 65 | + } |
| 66 | + } |
| 67 | + |
| 68 | + private void swap(int[] nums, int i, int j) { |
| 69 | + int tmp = nums[i]; nums[i] = nums[j]; nums[j] = tmp; |
| 70 | + } |
| 71 | +} |
| 72 | +``` |
| 73 | + |
| 74 | +### Src Code Analysis |
| 75 | + |
| 76 | +Two cases when the recursion ceases: |
| 77 | +a. left bound equals right bound; |
| 78 | +b. final index of pivot equals K. |
| 79 | + |
| 80 | +Since 'Kth **largest**' is wanted, numbers greater than pivot are placed to the left and numbers smaller to the right, which is a little different with typical quick sort code. |
| 81 | + |
| 82 | +### Complexity |
| 83 | + |
| 84 | +Time Complexity. Worse case (when the array is sorted): ***n + n - 1 + ... + 1 = O(n^2)*** . Amortized complexity: ***n + n/2 + n/4 + ... + 1 = O(2n)=O(n)*** . |
| 85 | + |
| 86 | +Space complexity is ***O(1)*** . |
0 commit comments