數組中的第K個最大元素
1.題目
- 數組中的第K個最大元素 - 力扣(LeetCode)
https://leetcode-cn.com/problems/kth-largest-element-in-an-array/
在未排序的數組中找到第 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 ≤ 數組的長度。
題目模板
/**
* @param {number[]} nums
* @param {number} k
* @return {number}
*/
var findKthLargest = function(nums, k) {
};
2.思路分析
見題解
3.所用到的方法
見題解
4.題解及優化
我的題解
不就是排序後找倒數第k個元素麼
let findKthLargest = (nums, k) => {
return nums.sort((a, b) => a - b)[nums.length - k]
}
或是倒排取正:
let findKthLargest = (nums, k) => {
return nums.sort((a, b) => b - a)[k - 1]
}
在冒泡排序過程中取值:
let findKthLargest = (nums, k) => {
for (let i = 0; i < k; i++) {
for (let j = nums.length - 1; j > i && j > 0; j--) {
[nums[j], nums[j - 1]] = nums[j] > nums[j - 1] ? [nums[j - 1], nums[j]] : [nums[j], nums[j - 1]]
}
}
return nums[k - 1]
}
。。。性能好差
使用堆排序:
let len // 因爲聲明的多個函數都需要數列長度,所以把len設置成爲全局變量
/**
* 堆調整
* @param arr 需要調整的數組
* @param i 預調整元素下標
*/
let adjustHeap = (arr, i) => {
let left = 2 * i + 1
let right = 2 * i + 2
// arr[i]預調整元素
let max = i
// 下面兩步找到左右子樹中最大的一個的下標
if (left < len && arr[left] > arr[max]) {
max = left
}
if (right < len && arr[right] > arr[max]) {
max = right
}
// 將左右子樹的最大值賦給父節點(裏面執行說明min有變動)
if (max !== i) {
[arr[max], arr[i]] = [arr[i], arr[max]]
adjustHeap(arr, max) // 這步遞歸爲確保本枝杈下端的最大值提到當前父端(arr[max])
}
}
/**
* @param {number[]} nums
* @param {number} k
* @return {number}
*/
let findKthLargest = function(nums, k) {
len = nums.length
// 構建大頂堆
for (let i = Math.floor(len / 2); i >= 0; i--) {
adjustHeap(nums, i)
}
// 堆排序
for (let i = len - 1; i >= nums.length -k; i--) {
// 將堆頂(樹根)置換到相應位置
[nums[0], nums[i]] = [nums[i], nums[0]]
len-- // 此時len表示的是未排序的arr長度
adjustHeap(nums, 0)
}
return nums[nums.length - k]
}
還不錯