题目
给定整数数组
nums和整数k,请返回数组中第k个最大的元素。
输入: [3,2,3,1,2,4,5,5,6], k = 4
输出: 4
题解
第一种
我们在partation函数中先声明三个变量,x变量作为分区的基准值默认值为s参数中的r位置值,然后我们在声明两个指针i和j,分别指向左边界和右边界,然后我们使用两个while循环分别找到第一个大于等于x的元素和第一个小于x的元素并将它们交换位置,我们不断重复这个过程,直到i和j相遇,我们将基准值x放到i的位置上,并返回i,函数findKthLargest接收两个参数,分别是数组nums和目标位置k,我们在函数中先声明两个指针low和high,分别指向数组的左右边界,然后我们使用while循环不断将数组分为两部分,直到找到目标位置为止,在每一轮循环中,我们先调用partation函数将数组分为两部分,并得到基准值x的位置i,然后我们将目标位置转换为数组下标,如果i小于目标位置,我们则在右半部分继续查找,如果i大于目标位置,我们则在左半部分继续查找,如果i等于目标位置,我们则直接返回x,如果没有找到目标位置,我们则返回-1即可
function partation(s, l, r) {
let x = s[r]
let i = l
let j = r
while (i < j) {
while (i < j && s[i] <= x) {
i++
}
if (i < j) {
s[j] = s[i]
j--
}
while (i < j && s[j] > x) {
j--
}
if (i < j) {
s[i] = s[j]
i++
}
}
s[i] = x
return i
}
function findKthLargest(nums, k) {
let low = 0
let high = nums.length - 1
while (low <= high) {
let i = partation(nums, low, high)
let target = nums.length - k
if (i < target) {
low = i + 1
} else if (i > target) {
high = i - 1
} else {
return nums[i]
}
}
return -1
}
第二种
我们这里使用快排的思想进行实现,我们在findKthLargest的函数中声明了一个名为traversal的递归函数,这个函数接受三个参数,一个数组nums,一个起始位置start和一个结束位置end,在函数中我们先判断start是否大于end,如果是我们则直接返回,否则我们就将数组中的第一个元素作为当前元素current,我们在声明一个变量index表示当前元素的索引,我们进行遍历数组中从start+1到end的元素,如果当前元素比current小,我们则将index加1并将当前元素和nums[index]交换位置,然后我们将当前元素和nums[index]交换位置,这样数组就被分为了两个部分,左边的元素都比nums[index]小,右边的元素都比nums[index]大,然后我们计算出目标位置target,如果index等于target,我们则直接返回nums[index],如果index大于target,我们则递归调用traversal函数,查找数组左半部分中第k大的元素,否则递归查找数组右半部分中第k大的元素,最后,我们将traversal函数返回值返回出去即可
function findKthLargest(nums, k) {
function traversal(nums, start, end){
if(start > end) return
let current = nums[start]
let index = start
for(let i = start + 1; i <= end; i ++){
if(current > nums[i]){
index ++
[nums[i], nums[index]] = [nums[index], nums[i]]
}
}
[nums[start], nums[index]] = [nums[index], nums[start]]
let target = nums.length - k
if(index === target) return nums[index]
return index > target ? traversal(nums, start, index) : traversal(nums, index + 1, end)
}
return traversal(nums, 0, nums.length - 1)
};
坚持努力,无惧未来!