返回
巧解LeetCode 239:滑动窗口最大值,二叉堆显神通!
前端
2023-11-06 16:05:42
引言
LeetCode上大名鼎鼎的239题,考察的是在滑动窗口内寻找最大值的经典问题。而二叉堆作为一种高效的数据结构,将在此题中大显神通,助你轻松攻克。
二叉堆简介
二叉堆是一种完全二叉树,其元素按照特定规则排序。大顶堆中,每个节点的值均大于其子节点的值,而小顶堆中则相反。二叉堆支持高效的插入、删除和查找最大值/最小值操作。
二叉堆解法
此题的解法思路如下:
- 初始化一个大顶堆,用于存储窗口内的元素。
- 窗口从数组中移动时:
- 移出窗口左端的元素(从堆中删除)。
- 移入窗口右端的元素(插入堆中)。
- 每次将元素插入堆后,从堆中取出最大值即可得到窗口内的最大值。
JavaScript实现
/**
* 使用二叉堆求滑动窗口最大值
* @param {number[]} nums
* @param {number} k
* @return {number[]}
*/
const maxSlidingWindow = (nums, k) => {
const heap = new MaxHeap();
const result = [];
for (let i = 0; i < nums.length; i++) {
if (i >= k) heap.delete(nums[i - k]);
heap.insert(nums[i]);
result.push(heap.max());
}
return result;
};
// 大顶堆类
class MaxHeap {
constructor() {
this.heap = [];
}
insert(val) {
this.heap.push(val);
this.siftUp(this.heap.length - 1);
}
delete(val) {
const index = this.heap.indexOf(val);
if (index < 0) return;
this.swap(index, this.heap.length - 1);
this.heap.pop();
this.siftDown(index);
}
max() {
return this.heap[0];
}
siftUp(index) {
while (index > 0) {
const parentIndex = Math.floor((index - 1) / 2);
if (this.heap[index] > this.heap[parentIndex]) {
this.swap(index, parentIndex);
index = parentIndex;
} else break;
}
}
siftDown(index) {
while (index < this.heap.length) {
const leftIndex = 2 * index + 1;
const rightIndex = 2 * index + 2;
let maxIndex = index;
if (leftIndex < this.heap.length && this.heap[leftIndex] > this.heap[maxIndex]) {
maxIndex = leftIndex;
}
if (rightIndex < this.heap.length && this.heap[rightIndex] > this.heap[maxIndex]) {
maxIndex = rightIndex;
}
if (maxIndex === index) break;
this.swap(index, maxIndex);
index = maxIndex;
}
}
swap(i, j) {
const temp = this.heap[i];
this.heap[i] = this.heap[j];
this.heap[j] = temp;
}
}
结语
二叉堆的强大之处在于其时间复杂度为O(logN),使算法在面对大规模数据时也能保持高效。希望本篇文章能为你提供一个清晰的理解,助你轻松攻破239题!
SEO关键词: