给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。
请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。
示例 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 <= 105-104 <= nums[i] <= 104
快速排序(超时)
TypeScript
function findKthLargest(nums: number[], k: number): number {
const n = nums.length
const target = n - k
const quickSort = (num: number[], left: number, right: number, target: number): number => {
if(left>=right) return num[left]
//随机生成下标作为基准
const randomIndex = left + Math.floor(Math.random() * (right - left + 1));
const stand = num[randomIndex];
//交换至最右边 注意:;分号别忘了,不然报错
[num[right], num[randomIndex]] =[num[randomIndex], num[right]];
let storeId = left
for (let i = left; i < right; i++) {
if (num[i] < stand) {
[num[i], num[storeId]] = [num[storeId], num[i]]
storeId++
}
}
[num[storeId], num[right]] = [num[right], num[storeId]]
if (storeId === target) {
return num[storeId]
} else if (storeId < target) {
return quickSort(num, storeId + 1, right, target)
} else {
return quickSort(num, left, storeId - 1, target)
}
}
return quickSort(nums, 0, n - 1, target)
};
还不如暴力解法🙄
TypeScript
function findKthLargest(nums: number[], k: number): number {
nums.sort((a,b)=>b-a)
return nums[k-1]
};
最终通过版
1.随机下标,把数组分成三部分:
left\[\]:大于随机下标的数
right\[\]:小于随机下标的数
equal\[\]:等于随机下标的数
【类似降序】
2.第k大,是从左往右第k大的元素
k的值小于等于left.length=>证明k在左边left\[\]数组里面
k的值大于left.length + equal.length =>证明k在右边right\[\]数组里面
都不符合以上两种,就是equal\[\]里,取0下标就行
TypeScript
function findKthLargest(nums: number[], k: number): number {
const left:number[] = []
const right:number[] = []
const equal:number[] = []
let rand = Math.floor(Math.random()*nums.length)
for(let i=0;i<nums.length;i++){
const cur = nums[i]
if(cur>nums[rand]){
left.push(cur)
}else if (cur < nums[rand]){
right.push(cur)
}else{
equal.push(cur)
}
}
if(k<=left.length){
return findKthLargest(left,k)
}else if(k>left.length + equal.length){
return findKthLargest(right,k-left.length-equal.length)
}else{
return equal[0]
}
};
共勉