题目描述
在未排序的数组中找到第 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
说明: 你可以假设 k 总是有效的,且 1 ≤ k ≤ 数组的长度。
解题思路
题目给定的数组是无序的,所以要想得到数组中第K个大的值,首先就得先给数组进行排序,排好序之后那么要想取得数组中第K个大的值就很简单了。
思路一 、 数组排序
根据题目可知给定数组是无序的,那么我们要返回第K个大的元素,那么第一想到的就应该是直接调用sort()给数组排序,如果升序,那么排序后的数组中的第K个大的元素即 nums[ nums.length - k ]为所求的值;如果是倒序,那么第 K 个大的元素即nums[ k - 1 ] 为所求的值。
思路二、 原地快排
给定一个中间值,一个左边界left,一个右边界right,将所有比这个中间值小的放在中间值的左边(或右边),比中间值大的放在中间值的右边(或左边),那么这时就可理解为现在有两个区域,左区域和右区域。之后再对这两个区域进行递归,即可实现原地快排。
AC代码
题解一 数组排序
var findKthLargest = function (nums, k) {
return nums.sort((a,b) => a-b)[nums.length - k]
}
题解二 原地快排
/**
* @param {number[]} nums
* @param {number} k
* @return {number}
*/
function partition(arr, left, right) {
if (left >= right) return // 终止条件,当数组左边界大于等于右边界时,就结束递归
let private = arr[left] // 给定中间值
let i = left, j = right
while (i < j) {
while (arr[j] <= private && i < j) { // 如果比中间值小,就放在右边
j--
}
arr[i] = arr[j] // 比中间值大就交换到前面
while (arr[i] >= private && i < j) { // 如果比中间值大,不动
i++
}
arr[j] = arr[i] // 如果比中间值小,就放在中间值的右边
}
arr[i] = private // 这是以 i 为分界,左边都是比中间值大的,右边都是比中间值小的,这是再把中间值重新赋给下标 i 的元素,就实现了一次排序
partition(arr, left, i - 1) // 对比中间值大的值即左边区域进行排序
partition(arr, i + 1, right) // 对比中间值小的值即右边区域进行排序
}
function sort(arr) {
partition(arr, 0, arr.length - 1)
return arr
}
var findKthLargest = function (nums, k) {
return sort(nums)[k-1]
};
总结
力扣上给的相关标签是堆和分治算法,不过我只想到排序,算法还有很远的路要走呀,明天也要加油哦。如果有小伙伴觉得还不错,希望可以点个赞哦
本文正在参与「掘金 2021 春招闯关活动」, 点击查看活动详情