# 0215. Kth Largest Element in an Array

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

## Description

Given an integer array `nums` and an integer `k`, return _the_ `kth` _largest element in the array_.

Note that it is the `kth` largest element in the sorted order, not the `kth` distinct element.

**Example 1:**

```
**Input:** nums = [3,2,1,5,6,4], k = 2
**Output:** 5
```

**Example 2:**

```
**Input:** nums = [3,2,3,1,2,4,5,5,6], k = 4
**Output:** 4
```

**Constraints:**

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

## ac1: quick select

Iterative version:

```java
class Solution {
    public int findKthLargest(int[] nums, int k) {
        // Edge cases: invalid input.

        k--; // Kth largest, index = k - 1 in sorted array.
        int start = 0, end = nums.length - 1;
        while (start <= end) {
            int p = getArrayPartitionIndex(nums, start, end);
            if (p == k) return nums[p];

            if (p < k) {
                start = p + 1;
            } else if (p > k) {
                end = p - 1;
            }
        }

        return -1;
    }

    private int getArrayPartitionIndex(int[] nums, int start, int end) {
        int pivot = nums[end];
        int left = start;
        for (int right = start; right < end; right++) {
            if (nums[right] >= pivot) {
                swap(nums, left, right);
                left++;
            }
        }
        swap(nums, left, end);
        return left;
    }

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

Recursive versioned:

```java
// quick select: set pivot, opposite direction two pointers

class Solution {
    public int findKthLargest(int[] nums, int k) {
        // sort, nlogn
        // partition, quick select
        // pivot, left/right

        // edge cases
        if (nums.length < 1) return -1;

        return quickSelect(nums, 0, nums.length-1, k);
    }
    private int quickSelect(int[] nums, int s, int e, int k) {
        // exit
        if (s == e) return nums[s];

        // init
        int l = s, r = e, pivot = nums[(s+e)/2];

        // loop
        while (l <= r) {
            while(l<=r && nums[l] > pivot) l++; // cannot put '==' here, will pass then entire list, cause stackoverfloww
            while (l <= r && nums[r] < pivot) r--;
            if (l <= r) {
                if (l < r) swap(nums, l, r);
                l++;
                r--;
            }
        }

        // determine which part contains kth
        if (s + k - 1 <= r) return quickSelect(nums, s, r, k);
        if (s + k - 1 >= l) return quickSelect(nums, l, e, k-(l-s)); //  be careful set new value for k by k-(l-s)
        return nums[r+1]; // when there is value in the middle, right, kth, left
    }
    private void swap(int[] nums, int i, int j) {
        int tmp = nums[i];
        nums[i] = nums[j];
        nums[j] = tmp;
    }
}

// Time: O(n)
```

## ac2: priority queue

O(NlogK)
