数组中的第K个最大元素

题目: 

在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。

示例 1:

输入: [3,2,1,5,6,4] 和 k = 2
输出: 5

示例 2:

输入: [3,2,3,1,2,4,5,5,6] 和 k = 4
输出: 4

说明:

你可以假设 k 总是有效的,且 1 ≤ k ≤ 数组的长度。

解题思路: 运用快速排序的思想, 每次选择后都能确定一个元素在数组中的位置, 当这个位置为nums.length - k时即找到了第K个最大元素

class Solution {
    public int findKthLargest(int[] nums, int k) {
        if(nums.length == 0 || k < 0)
            return -1;
        
        quickSelect(nums, k, 0, nums.length - 1);
        return nums[nums.length - k];
    }
    
    private int quickSelect(int[] nums, int k, int l, int r) {
        int index = partition(nums, l, r); //获取到下标判断与k的关系
        int target = nums.length - k;
        if(target == index)
            return nums[index];
        
        else if(target < index) {
            quickSelect(nums, k, l, index - 1);
        } else {
            quickSelect(nums, k, index + 1, r);
        }
        
        return -1;
    }
    
    /**
    该函数返回的是确定了位置的元素的下标
    **/
    private int partition(int[] nums, int left, int right) {
        int l = left, r = right;
        int cur = nums[left];
        while(l != r) {
            while(l < r && nums[r] >= cur) r--;
            while(l < r && nums[l] <= cur) l++;
            if(l < r) {
                swap(nums, l, r);
            }            
        }
        //把基准值放在他应该呆的位置
        swap(nums, left, r);
        return l;
    }
    
    private void swap(int[] nums, int l, int r) {
        int t = nums[l];
        nums[l] = nums[r];
        nums[r] = t;
    }
}