当前位置: 面试刷题>> 滑动窗口(经典算法150题)


### 题目描述补充 **题目:滑动窗口最大值** 给定一个数组 `nums` 和一个滑动窗口的大小 `k`,请找出该数组的滑动窗口中的最大值。滑动窗口从数组的最左边开始,每次向右移动一个位置,直到无法再移动为止。 **示例 1**: ``` 输入: nums = [1,3,-1,-3,5,3,6,7], k = 3 输出: [3,3,5,5,6,7] 解释: 滑动窗口的位置 最大值 --------------- ----- [1 3 -1] -3 5 3 6 7 3 1 [3 -1 -3] 5 3 6 7 3 1 3 [-1 -3 5] 3 6 7 5 1 3 -1 [-3 5 3] 6 7 5 1 3 -1 -3 [5 3 6] 7 6 1 3 -1 -3 5 [3 6 7] 7 ``` **要求**: - 你可以使用双端队列(deque)来解决这个问题,以便在 O(1) 时间复杂度内完成插入、删除和获取最大值的操作。 - 请使用 PHP、Python、JavaScript 编写你的解决方案。 ### 示例代码 #### PHP 示例 ```php function maxSlidingWindow($nums, $k) { $deque = new SplDoublyLinkedList(); // 使用 PHP 的双向链表模拟双端队列 $result = []; for ($i = 0; $i < count($nums); $i++) { // 移除窗口之外的元素 if (!$deque->isEmpty() && $deque->bottom() < $i - $k + 1) { $deque->shift(); } // 移除比当前元素小的元素,保证队列头部是最大值 while (!$deque->isEmpty() && $nums[$deque->top()] < $nums[$i]) { $deque->pop(); } $deque->push($i); // 插入当前元素的索引 // 当窗口形成后,开始记录结果 if ($i >= $k - 1) { $result[] = $nums[$deque->bottom()]; } } return $result; } ``` **注意**: PHP 标准库中没有直接的双端队列实现,这里使用 `SplDoublyLinkedList` 作为替代,并手动管理头部和尾部的操作。 #### Python 示例 ```python from collections import deque def maxSlidingWindow(nums, k): deque = deque() result = [] for i in range(len(nums)): # 移除窗口之外的元素 if deque and deque[0] == i - k: deque.popleft() # 移除比当前元素小的元素,保证队列头部是最大值 while deque and nums[deque[-1]] < nums[i]: deque.pop() deque.append(i) # 插入当前元素的索引 # 当窗口形成后,开始记录结果 if i >= k - 1: result.append(nums[deque[0]]) return result ``` #### JavaScript 示例 ```javascript function maxSlidingWindow(nums, k) { const deque = []; const result = []; for (let i = 0; i < nums.length; i++) { // 移除窗口之外的元素 if (deque.length > 0 && deque[0] === i - k) { deque.shift(); } // 移除比当前元素小的元素,保证队列头部是最大值 while (deque.length > 0 && nums[deque[deque.length - 1]] < nums[i]) { deque.pop(); } deque.push(i); // 插入当前元素的索引 // 当窗口形成后,开始记录结果 if (i >= k - 1) { result.push(nums[deque[0]]); } } return result; } ``` 以上代码均实现了滑动窗口的最大值查找,通过双端队列(deque)在 O(1) 时间复杂度内完成窗口内最大值的更新。
推荐面试题