C++面试题(46)------滑动窗口的最大值
- 操作系统:ubuntu22.04
- IDE:Visual Studio Code
- 编程语言:C++11
题目描述、
定一个数组 nums 和一个大小为 k 的滑动窗口,窗口每次向右移动一位,请找出所有窗口中的最大值。
示例:
输入: nums = [1,3,-1,-3,5,3,6,7], k = 3
输出: [3,3,5,5,6,7]
解法思路:单调队列
这是一个非常经典的滑动窗口 + 单调队列应用题。
🔍 核心思想:
使用一个双端队列 deque 来维护当前窗口中可能成为最大值的元素索引,并保证队列头部始终是当前窗口的最大值索引。
具体步骤如下:
- 遍历数组,维护一个窗口大小为 k 的滑动窗口;
- 对于每个新元素:
- 移除队列中不在窗口内的索引(超出窗口左边界);
- 移除队列中比当前元素小的值(因为它们不可能再成为最大值);
- 将当前元素索引入队;
- 当窗口满足大小 k 时,记录队列头部元素作为当前窗口最大值。
实现代码
#include <deque>
#include <vector>
using namespace std;class Solution {
public:vector< int > maxSlidingWindow( vector< int >& nums, int k ){vector< int > result;deque< int > dq; // 存储索引,对应值从大到小for ( int i = 0; i < nums.size(); ++i ){// 移除不在窗口内的索引while ( !dq.empty() && dq.front() < i - k + 1 )dq.pop_front();// 移除比当前元素小的值while ( !dq.empty() && nums[ dq.back() ] <= nums[ i ] )dq.pop_back();dq.push_back( i );// 添加最大值if ( i >= k - 1 )result.push_back( nums[ dq.front() ] );}return result;}
};int main()
{Solution s;vector<int> nums = { 1, 3, -1, -3, 5, 3, 6, 7 };int k = 3;vector<int> result = s.maxSlidingWindow( nums, k );for ( int i = 0; i < result.size(); i++ )cout << result[ i ] << " ";
}
运行结果
3 3 5 5 6 7