题目
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.
Example 1:
Input: [3,2,1,5,6,4] and k = 2Output: 5
Example 2:
Input: [3,2,3,1,2,4,5,5,6] and k = 4Output: 4
Note:
You may assume k is always valid, 1 ≤ k ≤ array’s length.
题意
找到数组中第K大的数。
思路
最简单的方法是直接排序,再取第K大的数。
更高效的方法是分治法,利用快速排序的partition来选出第K大。
代码实现
Java
排序
class Solution {public int findKthLargest(int[] nums, int k) {Arrays.sort(nums);return nums[nums.length - k];}}
分治法(二路快排)
class Solution {public int findKthLargest(int[] nums, int k) {int left = 0, right = nums.length - 1;while (left < right) {int p = partition(nums, left, right);if (p < k - 1) {left = p + 1;} else if (p > k - 1) {right = p - 1;} else {return nums[p];}}return nums[k - 1];}private int partition(int[] nums, int left, int right) {int i = left, j = right + 1;// 随机选择一个元素当作参考标准(这一步很重要)int r = new Random().nextInt(right - left + 1) + left;swap(nums, left, r);int temp = nums[left];while (true) {while (nums[++i] > temp) {if (i == right) break;}while (nums[--j] < temp) {if (j == left) break;}if (i >= j) break;swap(nums, i, j);}swap(nums, left, j);return j;}private void swap(int[] nums, int i, int j) {int temp = nums[i];nums[i] = nums[j];nums[j] = temp;}}
分治法(三路快排)
class Solution {public int findKthLargest(int[] nums, int k) {return partition(nums, 0, nums.length - 1, k);}private int partition(int[] nums, int left, int right, int k) {int i = left, p = left, q = right;int temp = nums[new Random().nextInt(right - left + 1) + left]; // 随机化很重要// 将指定范围数组分为三个区域while (i <= q) {if (nums[i] > temp) {swap(nums, i++, p++);} else if (nums[i] < temp) {swap(nums, i, q--);} else {i++;}}// 判断第K大在哪个区域,并对应处理if (k < p - left + 1) {return partition(nums, left, p - 1, k);} else if (k > q - left + 1) {return partition(nums, q + 1, right, k - q + left - 1);} else {return nums[p];}}private void swap(int[] nums, int i, int j) {int temp = nums[i];nums[i] = nums[j];nums[j] = temp;}}
JavaScript
/*** @param {number[]} nums* @param {number} k* @return {number}*/var findKthLargest = function (nums, k) {let left = 0, right = nums.length - 1while (left < right) {const p = partition(nums, left, right)if (p < k - 1) {left = p + 1} else if (p > k - 1) {right = p - 1} else {return nums[p]}}return nums[k - 1]}function partition(nums, left, right) {let tmp = nums[left]while (left < right) {while (left < right && nums[right] <= tmp) {right--}nums[left] = nums[right]while (left < right && nums[left] > tmp) {left++}nums[right] = nums[left]}nums[left] = tmpreturn left}
