11 滑动窗口最大值

给你一个整数数组 nums,有一个大小为 k的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 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

示例 2:

复制代码
输入:nums = [1], k = 1
输出:[1]

提示:

  • 1 <= nums.length <= 105
  • -104 <= nums[i] <= 104
  • 1 <= k <= nums.length

思路

1、创建一个大小为k的大顶堆,用pair<int,int>构建元素,第一个是数组的值,第二个是数组的下标。创建两个指针,left=0、right=k-1,把指针中间的数字先加入大顶堆,创建临时的vector用于存放最大值。

2、从堆顶拿一个元素,判断这个元素的下标是否是在left和right之间的,是则将元素放入答案中,否则将这个堆顶元素删除,继续获取堆顶元素,循环判断。

3、循环结束条件right要大于数组的下标时,结束循环。

cpp 复制代码
class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
     vector<int> _ans;
     int n=nums.size();
     if(n<k) return _ans;
     priority_queue<pair<int,int> > max_head;
     for(int i=0;i<k;i++){
         max_head.push({nums[i],i});
     }
     int left=0,right=k-1;
     while(1){
        pair<int,int> emit=max_head.top();
        while(emit.second<left){
            max_head.pop();
            emit=max_head.top();
        }
        _ans.push_back(emit.first);
        left++;
        right++;
        if(right>=n) break;
        max_head.push({nums[right],right});
     }
     
     return _ans;
 }
};
cpp 复制代码
//priority_queue(优先队列)
#include <queue>  // priority_queue 在 <queue> 头文件中

//创建大顶堆
std::priority_queue<pair<int,int>> pri_queue; 
std::priority_queue<
    int,                     // 元素类型
    std::vector<int>,        // 底层容器(必须是 vector 或 deque)
    std::greater<int>        // 比较器:小顶堆
> min_heap;

pair<int,int>  emit;
//访问pair的第一个元素:emit.first
//访问pair的第二个元素:emit.second 

基本函数

操作 函数 O(log n) 说明
插入元素 push(value) O(log n) 插入元素到队列
删除堆顶 pop() O(log n) 移除优先级最高的元素
访问堆顶 top() O(1) 返回优先级最高的元素(不删除)
判空 empty() O(1) 队列是否为空
大小 size() O(1) 元素个数

底层容器选 vectordeque 有什么区别?

priority_queue 支持 vectordeque 作为底层容器(也支持其他满足条件的序列容器,如 list 不支持随机访问,所以不行)。两者的区别主要体现在内存布局性能特征上:

对比维度 std::vector<int> std::deque<int>
内存布局 连续内存,所有元素存储在一块连续的空间中 分段内存,由多个固定大小的内存块组成
缓存友好性 ✅ 极高,遍历/堆操作时 CPU 缓存命中率高 ❌ 较差,元素分散在不同内存块,缓存命中率低
内存扩容 容量不足时会重新分配并拷贝/移动所有元素,可能导致迭代器失效 新增块时不会移动已有元素,迭代器不会失效
内存开销 较小,仅有一个动态数组的开销 较大,需要额外维护指向各个块的指针数组
尾部插入性能 均摊 O(1),但扩容时有峰值开销 均摊 O(1),无峰值开销
适用场景 优先推荐,性能更好 当需要避免扩容时移动开销巨大的元素类型时可选

推荐一个零声教育学习教程,个人觉得老师讲得不错,分享给大家:[Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK等技术内容,点击立即学习:链接

相关推荐
原野池予29 分钟前
深入Java集合框架:数组与List互转底层原理剖析(JDK 8)
java·数据结构·list
今日无bug1 小时前
列表转树:一道题搞懂 HashMap 在算法里的价值
前端·数据结构
何以解忧,唯有..1 小时前
预订酒店问题
算法
No8g攻城狮1 小时前
【算法】什么是 DFS 与 BFS 及他们的区别
算法·深度优先·宽度优先
zww89491112 小时前
家政派单系统实战指南:从需求分析到智能调度算法落地
算法·需求分析
手写码匠2 小时前
华为云Flexus+DeepSeek征文|Dify 多 Agent 评测实战:用 DeepSeek-R1 当裁判,打造多智能体系统的自动化质量保障体系
人工智能·深度学习·算法·aigc
ZC跨境爬虫2 小时前
LeetCode 88. 合并两个有序数组(双指针详解 + Java Python 实现)
java·python·算法·leetcode
Nil2082 小时前
leetcode 238除了自身以外数组的乘积
数据结构·算法·leetcode
土司大王2 小时前
LeetCode hot100——最长连续序列
数据结构·算法·leetcode
caimouse2 小时前
ReactOS 图形系统分析(17):区域填充 — EngPaint / IntEngPaint(paint.c)
c语言·开发语言·算法