Kth Largest Element in an Array

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 [3,2,1,5,6,4] and k = 2, return 5.

Note: 
You may assume k is always valid, 1 ≤ k ≤ array's length.

解题思路:

这题是比较古老的排序题目了,经典的表述是求数组中第k大或者第k小的数字。这种题,用一个O(nlogn)的比较排序,然后直接取第k个 第(前)k大数问题 的总结。

我以前也转载过相关解法 求已知N个数中第k小的数

这道题的解法是比较综合的。首先,递归分治,借鉴了快速排序的思路,将数组根据任意元素(这里取第一个)分成两半,a.如果从end到pivot正好k个,那么就是第pivot个元素。b.如果end到pivot>k个,递归处理pivot+1到end,取第k个。c.如果小于k个,则取前半段(start到pivot-1),取第k-(end - pivot+1)个。

其次,根据上面的表述,和binary search也很像吧。一不小心就会出现stack overflow的问题,开始我就写错了,注释掉了。因为在pivot==start的时候,start得不到更新,死循环了。

时间复杂度,因为上面的b和c每次只选择执行一次,而不是像快排,每次两个都要执行。所以时间复杂度为O(n)。

因为O(n+n/2+n/4...) = O(2n)。

public class Solution {

    public int findKthLargest(int[] nums, int k) {

        return find(nums, 0, nums.length - 1, k);

    }

    

    public int find(int[] nums, int start, int end, int k) {

        if(start > end) {

            return -1;

        }

        int pivot = partition(nums, start, end);

        if(end - pivot + 1 == k) {

            return nums[pivot];

        } else if(end - pivot + 1 > k) {

            // return find(nums, pivot, end, k);

            return find(nums, pivot + 1, end, k);

        } else {

            return find(nums, start, pivot - 1, k - (end - pivot + 1));

        }

    }

    

    public int partition(int[] nums, int start, int end) {

        if(start == end) {

            return start;

        }

        int pivot = start + 1;

        for(int i = start + 1; i <= end; i++) {

            if(nums[i] < nums[start]) {

                int temp = nums[pivot];

                nums[pivot] = nums[i];

                nums[i] = temp;

                pivot++;

            }

        }

        int temp = nums[pivot - 1];

        nums[pivot - 1] = nums[start];

        nums[start] = temp;

        return pivot - 1;

    }

}

 

你可能感兴趣的:(element)