LeetCode – Kth Largest Element in an Array (Java)

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.

Java Solution 1 – Sorting

public int findKthLargest(int[] nums, int k) {
    Arrays.sort(nums);
    return nums[nums.length-k];
}

Time is O(nlog(n)). The problem of this solution is that sorting all elements is not necessary and is a overkill for getting just one element.

Java Solution 2 – Heap

We can use a min heap to solve this problem. The heap stores the top k largest elements.The top of the heap is the Kth Largest element and all other elements are greater than the heap top. Whenever the size is greater than k, delete the min. Time complexity is O(nlog(k)). Space complexity is O(k) for storing the top k numbers.

public int findKthLargest(int[] nums, int k) {
    PriorityQueue<Integer> q = new PriorityQueue<Integer>(k);
    for(int i: nums){
        q.offer(i);
 
        if(q.size()>k){
            q.poll();
        }
    }
 
    return q.peek();
}

Time complexity of n*log(k) is an improvement to Solution 1. However, this solution requires O(k) space complexity and it is also maintained k-element heap.

Java Solution 3 – Quick Sort

This problem can also be solved by using a similar method like quicksort.

public int findKthLargest(int[] nums, int k) {
	if (k < 1 || nums == null) {
		return 0;
	}
 
	return getKth(nums.length - k +1, nums, 0, nums.length - 1);
}
 
public int getKth(int k, int[] nums, int start, int end) {
 
	int pivot = nums[end];
 
	int left = start;
	int right = end;
 
	while (true) {
 
		while (nums[left] < pivot && left < right) {
			left++;
		}
 
		while (nums[right] >= pivot && right > left) {
			right--;
		}
 
		if (left == right) {
			break;
		}
 
		swap(nums, left, right);
	}
 
	swap(nums, left, end);
 
	if (k == left + 1) {
		return pivot;
	} else if (k < left + 1) {
		return getKth(k, nums, start, left - 1);
	} else {
		return getKth(k, nums, left + 1, end);
	}
}
 
public void swap(int[] nums, int n1, int n2) {
	int tmp = nums[n1];
	nums[n1] = nums[n2];
	nums[n2] = tmp;
}

Average case time is O(n), worst case time is O(n^2).

Reference:
http://www.cs.yale.edu/homes/aspnes/pinewiki/QuickSelect.html

12 thoughts on “LeetCode – Kth Largest Element in an Array (Java)”

  1. PriorityQueue is by default the maxHeap, it should be minHeap

    PriorityQueue minHeap = new PriorityQueue(new Comparator() {
    @Override
    public int compare(Integer a, Integer b) {
    return a – b;
    }
    });

  2. A guaranteed processing O(K log N) and space O(N) solution is:
    1- Build max heap with the contents of the array O(N)
    2- remove first K elements (K log N)
    3- the Kth max is the last removed element in step 2

    Also, just a note: the average case time for the given solution (quickselect) is O(n) _only_ when using randomized pivot selection (just like in quick sort), not for the naive selection logic used in the example.

  3. i think original post is correct, it should be k since the calculation is always based on the indexs of nums,

  4. for the recursive code above, the last condition(k > left + 1), the 1st parameter for recursive function should be (k – left – 1)

  5. An O(NlogK) solution applying MinHeap:


    public static int solution_1(int[] arr, int k) throws Exception {
    //parameter check
    assert (arr != null && arr.length > 0 && k > 0 && k <= arr.length);
    MinHeap minHeap = new MinHeap(k);
    for(int i = 0; i < arr.length; ++i) {
    if(minHeap.getCurSize() < k) minHeap.insert(arr[i]);
    else if(minHeap.peek() < arr[i]) {
    minHeap.getHeapArray()[0] = arr[i];
    minHeap.siftDown(0);
    }
    }
    return minHeap.removeMin();
    }
    public static void main(String[] args) throws Exception {
    System.out.println(solution_1(new int[]{3,2,1,5,6,4}, 1));
    System.out.println(solution_1(new int[]{3,2,1,5,6,4}, 2));
    System.out.println(solution_1(new int[]{3,2,1,5,6,4}, 3));
    System.out.println(solution_1(new int[]{3,2,1,5,6,4}, 4));
    System.out.println(solution_1(new int[]{3,2,1,5,6,4}, 5));
    System.out.println(solution_1(new int[]{3,2,1,5,6,4}, 6));
    System.out.println(solution_1(new int[]{4,6,5,1,2,3}, 1));
    System.out.println(solution_1(new int[]{4,6,5,1,2,3}, 2));
    System.out.println(solution_1(new int[]{4,6,5,1,2,3}, 3));
    System.out.println(solution_1(new int[]{4,6,5,1,2,3}, 4));
    System.out.println(solution_1(new int[]{4,6,5,1,2,3}, 5));
    System.out.println(solution_1(new int[]{4,6,5,1,2,3}, 6));
    }

Leave a Comment