返回
LeetCode题解:239. 滑动窗口最大值,暴力算法与优化详解,JavaScript实现
前端
2023-09-28 22:39:39
导言
滑动窗口问题是一种常见的数据结构和算法问题,涉及在一个数据序列的子集(窗口)上进行操作,并随着窗口在序列中移动而更新结果。在“滑动窗口最大值”问题中,我们的目标是找到给定序列中所有可能滑动窗口的最大值。
暴力算法
暴力算法采用双重循环枚举所有可能的滑动窗口,计算每个窗口的最大值。它的时间复杂度为O(n^2),其中n是序列的长度。虽然简单易懂,但当n较大时,效率低下。
/**
* @param {number[]} nums
* @param {number} k
* @return {number[]}
*/
const maxSlidingWindow = function(nums, k) {
const result = [];
// 遍历每个滑块的起始点
for (let i = 0; i <= nums.length - k; i++) {
let max = nums[i];
// 遍历后续滑块元素
for (let j = i + 1; j < i + k; j++) {
if (nums[j] > max) {
max = nums[j];
}
}
result.push(max);
}
return result;
};
优化算法
优化算法使用一个单调队列(双端队列)来跟踪窗口中元素的递减顺序。当窗口移动时,单调队列可以高效地维护窗口中的最大值。时间复杂度降至O(n)。
/**
* @param {number[]} nums
* @param {number} k
* @return {number[]}
*/
const maxSlidingWindow = function(nums, k) {
const result = [];
const deque = [];
// 遍历数组
for (let i = 0; i < nums.length; i++) {
// 移除deque中所有小于当前元素的元素
while (deque.length && nums[deque[deque.length - 1]] < nums[i]) {
deque.pop();
}
// 将当前元素加入deque
deque.push(i);
// 如果队首元素不在当前窗口中,则移除
if (deque[0] <= i - k) {
deque.shift();
}
// 当窗口长度达到k时,将队首元素加入结果
if (i >= k - 1) {
result.push(nums[deque[0]]);
}
}
return result;
};
比较
算法 | 时间复杂度 | 空间复杂度 |
---|---|---|
暴力算法 | O(n^2) | O(1) |
优化算法 | O(n) | O(k) |
优化算法在时间复杂度方面具有显着优势,尤其是在序列长度较大时。
总结
本文介绍了两种解决LeetCode题解第239题“滑动窗口最大值”的算法:暴力算法和优化算法。我们使用JavaScript进行了代码实现,并提供了详细的注释,以帮助理解算法的实现细节。优化算法通过使用单调队列大大提高了效率,并降低了时间复杂度至O(n)。希望这篇文章能帮助你深入理解滑动窗口问题和算法实现。