Kth Largest Element in an Array

Code link: https://leetcode.com/problems/kth-largest-element-in-an-array/

Constraint:

  • 1 <= k <= nums.length <= 104
  • -104 <= nums[i] <= 104

Idea

With the help of Priority heap, we can easily get the Kth largest elements. Since the PriorityQueue in JDK is a min-heap by default, we need to provide our own comparator to reverse the ordering.

Code

  • Attemp 1 using lambda
class Solution {
    public int findKthLargest(int[] nums, int k) {
        Queue<Integer> pq = new PriorityQueue<>((a, b) -> b - a);
        for (int i : nums) {
            pq.offer(i);
        }
        
        for (int i = 0; i < k - 1; i++) {
            pq.poll();
        }
        
        return pq.poll();
    }
}
  • Attemp 2 using Comparator interface
class Solution {
    public int findKthLargest(int[] nums, int k) {
        Queue<Integer> pq = new PriorityQueue<>(new Comparator<Integer>(){
            @Override
            public int compare(Integer a, Integer b) {
                return b - a;
            }
        });
        
        for (int i : nums) {
            pq.offer(i);
        }
        
        for (int i = 0; i < k - 1; i++) {
            pq.poll();
        }
        
        return pq.poll();
    }
}
  • Time: O(nlogn). The operation offer() and poll() each takes O(logn) and we need to repeast for K times. K could be as large as array size.

  • Space: O(n) as potentailly we have to store all elements in the queue.

  • Attemp 3 using Quick Select
    The basic idea of Quick Select is that we pick a value in the array as pivot, move all the greater (or equal) elements to its left side, and all the smaller elements to its right side. We repeat this process recursively until the Kth largest element's index (which is K-1 in an sorted array) is equal to the pivot index. The value at that index is the expected return value because all the element greater or equal to it are moved to its left side.

class Solution {
    public int findKthLargest(int[] nums, int k) {
        return findKthLargest(nums, 0, nums.length - 1, k);
    }
    
    private int findKthLargest(int[] nums, int start, int end, int k) {
        if (k > nums.length) {
            throw new IllegalArgumentException();
        }
        
        int pivotFinalIndex = start;
        int pivotValue = nums[end];
        for (int i = start; i < end; i++) {
            if (nums[i] >= pivotValue) {
                swap(nums, i, pivotFinalIndex++);
            }
        }
        
        swap(nums, pivotFinalIndex, end);
        if (k - 1 == pivotFinalIndex) {
            return nums[k - 1];
        } else if (k - 1 < pivotFinalIndex) {
            return findKthLargest(nums, start, pivotFinalIndex - 1, k);
        } else {
            return findKthLargest(nums, pivotFinalIndex + 1, end, k);
        }
    }
    
    private void swap(int[] nums, int i, int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
}
posted on 2021-07-31 23:32  blackraven25  阅读(24)  评论(0)    收藏  举报