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.

Tips:

两种方法,heap的复杂度是O(nlogk),quick sort的平均是O(n),经过shuffle input几乎可以保证是O(n)。

还有Quick Select(D & C):

n+(n/2)+(n/4)..1 = n + (n-1) = O(2n-1) = O(n), because n/2+n/4+n/8+..1=n-1

Code:

Quick Sort:

public class Solution {
    public int findKthLargest(int[] nums, int k) {
        shuffle(nums);
        int start = 0;
        int end = nums.length - 1;
        k = nums.length - k;
        while (start < end) {
            int pivot = partition(nums, start, end);
            if (pivot == k) {
                return nums[pivot];
            } else if (pivot < k) {
                start = pivot + 1;
            } else {
                end = pivot - 1;
            }
        }
        return nums[end];
    }

    private int partition(int[] nums, int start, int end) {
        int pivot = start;
        while (start <= end) {
            while (start <= end && nums[start] <= nums[pivot]) {
                start++;
            }
            while (start <= end && nums[end] >= nums[pivot]) {
                end--;
            }
            if (start < end) {
                swap(nums, start, end);
            }
        }
        swap(nums, pivot, end);
        return end;
    }

    private void swap(int[] nums, int i, int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }

    private void shuffle(int[] nums) {
        final Random random = new Random();
            for(int i = 1; i < nums.length; i++) {
                final int r = random.nextInt(i + 1);
                swap(nums, i, r);
            }
    }
}

Heap:

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

    final PriorityQueue<Integer> pq = new PriorityQueue<>();
    for(int val : nums) {
        pq.offer(val);

        if(pq.size() > k) {
            pq.poll();
        }
    }
    return pq.peek();
}

Quick Select:

public int findKthLargest(int[] nums, int k) {
    if (nums == null || nums.length == 0) return Integer.MAX_VALUE;
    return findKthLargest(nums, 0, nums.length - 1, nums.length - k);
}    

public int findKthLargest(int[] nums, int start, int end, int k) {// quick select: kth smallest
    if (start > end) return Integer.MAX_VALUE;

    int pivot = nums[end];// Take A[end] as the pivot, 
    int left = start;
    for (int i = start; i < end; i++) {
        if (nums[i] <= pivot) // Put numbers < pivot to pivot's left
            swap(nums, left++, i);            
    }
    swap(nums, left, end);// Finally, swap A[end] with A[left]

    if (left == k)// Found kth smallest number
        return nums[left];
    else if (left < k)// Check right part
        return findKthLargest(nums, left + 1, end, k);
    else // Check left part
        return findKthLargest(nums, start, left - 1, k);
} 

void swap(int[] A, int i, int j) {
    int tmp = A[i];
    A[i] = A[j];
    A[j] = tmp;                
}

results matching ""

    No results matching ""