feat: 数组中第k个最大值(215)
This commit is contained in:
parent
09c9e2c45e
commit
333aec6eaa
163
leetcode/中等/数组中第k个最大值.js
Normal file
163
leetcode/中等/数组中第k个最大值.js
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
/*
|
||||||
|
215. 数组中的第K个最大元素
|
||||||
|
中等
|
||||||
|
|
||||||
|
相关标签
|
||||||
|
相关企业
|
||||||
|
给定整数数组 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 思路1:排序之后直接取,但是不符合题目要求
|
||||||
|
/**
|
||||||
|
* @param {number[]} nums
|
||||||
|
* @param {number} k
|
||||||
|
* @return {number}
|
||||||
|
*/
|
||||||
|
const findKthLargest = function (nums, k) {
|
||||||
|
nums.sort((a, b) => a - b);
|
||||||
|
return nums[nums.length - k];
|
||||||
|
};
|
||||||
|
|
||||||
|
// 使用快速选择算法
|
||||||
|
/**
|
||||||
|
* @param {number[]} nums
|
||||||
|
* @param {number} k
|
||||||
|
* @return {number}
|
||||||
|
*/
|
||||||
|
const partition = (nums, left, right) => {
|
||||||
|
const pivot = nums[right];
|
||||||
|
let i = left;
|
||||||
|
for (let j = left; j < right; j++) {
|
||||||
|
if (nums[j] < pivot) {
|
||||||
|
[nums[i], nums[j]] = [nums[j], nums[i]];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[nums[i], nums[right]] = [nums[right], nums[i]];
|
||||||
|
return i;
|
||||||
|
};
|
||||||
|
|
||||||
|
const quickSelect = (nums, left, right, k) => {
|
||||||
|
if (left === right) return nums[left];
|
||||||
|
const pivotIndex = partition(nums, left, right);
|
||||||
|
if (pivotIndex === k) {
|
||||||
|
return nums[k];
|
||||||
|
} if (pivotIndex < k) {
|
||||||
|
return quickSelect(nums, pivotIndex + 1, right, k);
|
||||||
|
}
|
||||||
|
return quickSelect(nums, left, pivotIndex - 1, k);
|
||||||
|
};
|
||||||
|
|
||||||
|
const findKthLargest2 = function (nums, k) {
|
||||||
|
return quickSelect(nums, 0, nums.length - 1, nums.length - k);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 使用最小堆
|
||||||
|
class MinHeap {
|
||||||
|
constructor() {
|
||||||
|
this.heap = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
size() {
|
||||||
|
return this.heap.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
peek() {
|
||||||
|
return this.heap[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
insert(value) {
|
||||||
|
this.heap.push(value);
|
||||||
|
this.heapifyUp();
|
||||||
|
}
|
||||||
|
|
||||||
|
remove() {
|
||||||
|
if (this.size() === 1) {
|
||||||
|
return this.heap.pop();
|
||||||
|
}
|
||||||
|
const root = this.heap[0];
|
||||||
|
this.heap[0] = this.heap.pop();
|
||||||
|
this.heapifyDown();
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
heapifyUp() {
|
||||||
|
let index = this.size() - 1;
|
||||||
|
while (index > 0) {
|
||||||
|
const parentIndex = Math.floor((index - 1) / 2);
|
||||||
|
if (this.heap[parentIndex] <= this.heap[index]) break;
|
||||||
|
[this.heap[parentIndex], this.heap[index]] = [this.heap[index], this.heap[parentIndex]];
|
||||||
|
index = parentIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
heapifyDown() {
|
||||||
|
let index = 0;
|
||||||
|
const length = this.size();
|
||||||
|
const element = this.heap[0];
|
||||||
|
while (true) {
|
||||||
|
const leftChildIndex = 2 * index + 1;
|
||||||
|
const rightChildIndex = 2 * index + 2;
|
||||||
|
let leftChild; let
|
||||||
|
rightChild;
|
||||||
|
let swap = null;
|
||||||
|
|
||||||
|
if (leftChildIndex < length) {
|
||||||
|
leftChild = this.heap[leftChildIndex];
|
||||||
|
if (leftChild < element) {
|
||||||
|
swap = leftChildIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rightChildIndex < length) {
|
||||||
|
rightChild = this.heap[rightChildIndex];
|
||||||
|
if ((swap === null && rightChild < element) || (swap !== null && rightChild < leftChild)) {
|
||||||
|
swap = rightChildIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (swap === null) break;
|
||||||
|
[this.heap[index], this.heap[swap]] = [this.heap[swap], this.heap[index]];
|
||||||
|
index = swap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const findKthLargest3 = function (nums, k) {
|
||||||
|
const minHeap = new MinHeap();
|
||||||
|
|
||||||
|
for (const num of nums) {
|
||||||
|
minHeap.insert(num);
|
||||||
|
if (minHeap.size() > k) {
|
||||||
|
minHeap.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return minHeap.peek();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 示例测试
|
||||||
|
console.log(findKthLargest([3, 2, 1, 5, 6, 4], 2)); // 输出: 5
|
||||||
|
console.log(findKthLargest([3, 2, 3, 1, 2, 4, 5, 5, 6], 4)); // 输出: 4
|
||||||
|
console.log(findKthLargest2([3, 2, 1, 5, 6, 4], 2)); // 输出: 5
|
||||||
|
console.log(findKthLargest2([3, 2, 3, 1, 2, 4, 5, 5, 6], 4)); // 输出: 4
|
||||||
|
console.log(findKthLargest3([3, 2, 1, 5, 6, 4], 2)); // 输出: 5
|
||||||
|
console.log(findKthLargest3([3, 2, 3, 1, 2, 4, 5, 5, 6], 4)); // 输出: 4
|
Loading…
x
Reference in New Issue
Block a user