给定整数数组 nums
和整数 k
,请返回数组中第 **k**
个最大的元素。
请注意,你需要找的是数组排序后的第 k
个最大的元素,而不是第 k
个不同的元素。
示例 1:
输入: [3,2,1,5,6,4],
k = 2
输出: 5
示例 2:
输入: [3,2,3,1,2,4,5,5,6],
k = 4
输出: 4
提示:
1 <= k <= nums.length <= 10^4
-10^4 <= nums[i] <= 10^4
/**
* @param {number[]} nums
* @param {number} k
* @return {number}
*/
var findKthLargest = function(nums, k) {
};
解题1
Array.sort从大到小排序,并取值
/**
* @param {number[]} nums
* @param {number} k
* @return {number}
*/
var findKthLargest = function(nums, k) {
nums.sort((a, b) => b - a)
return nums[k - 1]
};
解题2
推排序
- 思路是维持一个单调递减堆stack
- 循环nums数组,
- 判断堆顶元素是否小于数组元素n,满足,则推入tmp中
- 直到stack为空或不满足上一步判断
- 如果stack的长度小于k,则推入n
- 如果stack的长度还小于k,并tmp有值,持续将tmp中的值填入stack
- 最后返回stack栈顶元素
/**
* @param {number[]} nums
* @param {number} k
* @return {number}
*/
var findKthLargest = function(nums, k) {
let stack = []
for (let i = 0; i < nums.length; i++) {
const n = nums[i], tmp = []
while(stack.length && stack[stack.length - 1] < n) {
tmp.push(stack.pop())
}
if (stack.length < k) stack.push(n)
while(tmp.length && stack.length < k) {
stack.push(tmp.pop())
}
}
return stack[stack.length - 1]
};
- 时间复杂度:O(NK),N = nums.length,K = k
- 空间复杂度:O(K)
解题3
快速排序,从大到小,取数组下标k-1的元素,即为所求。
因为题目只要求第K大的数字,所以不需要全部排序,只需要比较左右分的下标pos和k-1的大小,对部分区间进行排序即可
/**
* @param {number[]} nums
* @param {number} k
* @return {number}
*/
var findKthLargest = function(nums, k) {
quickSort(0, nums.length - 1)
return nums[k-1]
function quickSort(left, right) {
if (left < right) {
let pos = partition(left, right)
if (pos < k-1) quickSort(pos + 1, right)
if (pos > k-1) quickSort(left, pos - 1)
}
}
function partition(left, right) {
const pivot = nums[right]
let i = left
for(let j = left; j < right; j++) {
if (nums[j] >= pivot) {
swap(i++, j)
}
}
swap(i, right)
return i
}
function swap(i, j) {
const tmp = nums[i]
nums[i] = nums[j]
nums[j] = tmp
}
};