代码编织梦想

https://ac.nowcoder.com/acm/contest/22669/M

题目描述

给一个长度为N的数组,一个长为K的滑动窗体从最左端移至最右端,你只能看到窗口中的K个数,每次窗体向右移动一位,如下图:

你的任务是找出窗体在各个位置时的最大值和最小值。

输入描述:

第1行:两个整数N和K;
第2行:N个整数,表示数组的N个元素(≤2×10^9);

输出描述:

第一行为滑动窗口从左向右移动到每个位置时的最小值,每个数之间用一个空格分开;
第二行为滑动窗口从左向右移动到每个位置时的最大值,每个数之间用一个空格分开。

示例1

输入

8 3
1 3 -1 -3 5 3 6 7

输出

-1 -3 -3 -3 3 3
3 3 5 5 6 7

备注:

对于20%的数据,K≤N≤1000;
对于50%的数据,K≤N≤10^5;
对于100%的数据,K≤N≤10^6。

双指针+单调队列(数组实现)

#include<bits/stdc++.h>
using namespace std;
int a[1000005],p[1000005];    //p数组实现单调队列,储存的是a数组的下标
int main(){
    int n,k;
    cin>>n>>k;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }

    int hh=0,tt=-1;    //双指针,hh指向单调队列头元素,tt指向单调队列末位元素
    for(int i=1;i<=n;i++){
        while(hh<=tt&&p[hh]<=i-k)hh++;    //当头元素超出队列,hh+1,指向下一个元素
        while(hh<=tt&&a[p[tt]]>=a[i])tt--;    //维护单调递增,删去队列末尾大于即将插入元素的元素
        p[++tt]=i;    //入队
        if(i>=k)cout<<a[p[hh]]<<' ';    //从i=k时开始
    }


    cout<<endl;
    hh=0,tt=-1;    //同理
    for(int i=1;i<=n;i++){
        while(hh<=tt&&p[hh]<=i-k)hh++;
        while(hh<=tt&&a[p[tt]]<=a[i])tt--;
        p[++tt]=i;
        if(i>=k)cout<<a[p[hh]]<<' ';
    }
    return 0;
}

 自己写的shi码(vector+deque实现)

#include<bits/stdc++.h>
using namespace std;
int main(){
    int n,k;
    cin>>n>>k;
    vector<pair<int,int> >v;        //开pair数组(忘了开两个数组,一个存下标)
    for(int i=1;i<=n;i++){
        int a;
        cin>>a;
        v.push_back(make_pair(i,a));
    }


    deque<pair<int,int> >q;        //deque模拟单调队列(没必要的)
    for(int i=0;i<k-1;i++){        //先放入k-1个元素(没想到当i>=k时输出)
        if(q.empty())q.push_back(v[i]);    //判空
        else{
            while(q.empty()==0&&q.back().second>=v[i].second)q.pop_back();
            q.push_back(v[i]);    //维护单调
        }
    }
    for(int i=k;i<=n;i++){    //先维护单调,再插入尾部元素,再输出头部元素
        if(!q.empty()&&q.front().first<i-k+1)q.pop_front();
        if(q.empty())q.push_back(v[i]);
        else{
            while(q.empty()==0&&q.back().second>=v[i-1].second)q.pop_back();
            q.push_back(v[i-1]);
        }
        cout<<q.front().second<<' ';
    }

    cout<<endl;
    q.clear();
    for(int i=0;i<k-1;i++){        //以下同理
        if(q.empty())q.push_back(v[i]);
        else{
            while(q.empty()==0&&q.back().second<=v[i].second)q.pop_back();
            q.push_back(v[i]);
        }
    }
    for(int i=k;i<=n;i++){
        if(!q.empty()&&q.front().first<i-k+1)q.pop_front();
        if(q.empty())q.push_back(v[i]);
        else{
            while(q.empty()==0&&q.back().second<=v[i-1].second)q.pop_back();
            q.push_back(v[i-1]);
        }
        cout<<q.front().second<<' ';
    }
    return 0;
}

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/m0_53089164/article/details/129479689

双指针,滑动窗口,单调队列/栈_hhl35的博客-爱代码爱编程

双指针 解决问题 降维,优化时间复杂度 一般思路 暴力解法–>寻找性质(单调性)–>双指针 牛刀小试 给定排序的数组和一个target,寻找数组里两数之和为target的两个数的索引下标,若不存在返回

滑动窗口、双指针、单调队列和单调栈-爱代码爱编程

167. Two Sum II - Input array is sorted class Solution { public int[] twoSum(int[] numbers, int target) { int[] res = new int[2]; int i=0,j=numbers.length-1;

滑动窗口(单调队列)-爱代码爱编程

先简单描述一下单调队列: 单调队列和单调栈类似,就是队列内的元素是单调的,并且是满足出队顺序的单调性。它可以维护局部的单调性。由于单调队列可以队首出队以及前面的元素一定比后面的元素先入队的性质,使得它可以维护局部的单调性,并且当队首元素不在区间之内则可以出队,其复杂度也是线性的。 问题描述: 有一个长度为

滑动窗口+双指针+单调队列+单调栈-爱代码爱编程

双指针的应用 先暴力考虑是否有单调性利用单调性优化例 leetcode 167 两数之和II 如果暴力,就是两重循环。 双指针法 public int[] twoSum(int[] numbers, int target) { int left=0,right=numbers.length-1; int []r

滑动窗口/单调队列/双指针-爱代码爱编程

滑动窗口(双指针)的思路,一般用在某个连续的子序列/子数组里寻求某个满足答案的状态,关键在于采取什么样的数据结构去维护这个序列所应该有的状态。 滑动窗口模板: /* 滑动窗口算法框架 */ void slidingWindow(string s, string t) { unordered_map<char, int> need, w

算法学习之双指针、滑动窗口、单调队列、单调栈-爱代码爱编程

文章目录 双指针1.快慢指针2.左右指针3.其他滑动窗口76. 最小覆盖子串567. 字符串的排列438. 找到字符串中所有字母异位词单调栈496. 下一个更大元素 I739. 每日温度单调队列239. 滑动窗口最大值 双指针 1.快慢指针 判定链表中是否含有环已知链表中含有环,返回这个环的起始位置寻找链表的中点寻找链表的倒数第 k 个元素

html怎么做滑动窗口,单调队列(滑动窗口).html-爱代码爱编程

单调队列(滑动窗口) · GitBook Introduction并查集差分尺取法双指针法大数单调队列(滑动窗口)单调栈动态规划二分分治哈希表链表模拟排序前缀和三指针法设计树数论数学数组搜索回溯&枚举拓扑排序贪心图位运算优先队列栈字符串最小生成树LeetCode未分类ManacherOfferOrdered MapPublish

双指针 & 滑动窗口-爱代码爱编程

快慢指针 解决主要解决链表中的问题,比如典型的判定链表中是否包含环 快慢指针一般都初始化指向链表的头结点head,前进时快指针fast在前,慢指针slow在后,巧妙解决一些链表中的问题。 1、判定链表中是否含有环 用两个指针,一个跑得快,一个跑得慢。如果不含有环,跑得快的那个指针最终会遇到null,说明链表不含环;如果含有环,快指针最终会超慢指

239. 滑动窗口最大值(困难 单调队列 数组 滑动窗口)-爱代码爱编程

239. 滑动窗口最大值 给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。 返回滑动窗口中的最大值。 示例 1: 输入:nums = [1,3,-1,-3,5,3,6,7], k = 3 输出:[3,3,5,5,6,7] 解释: 滑动窗口的

滑动窗口(单调队列)讲解-爱代码爱编程

https://www.luogu.com.cn/problem/P1886   题目链接 有一个长为 n 的序列 a,以及一个大小为 k 的窗口。现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值。 例如: The array is [1,3,-1,-3,5,3,6,7], and k = 3。 观察样例可知,

【滑动窗口、双指针、单调队列】-爱代码爱编程

滑动窗口、双指针、单调队列 Leetcode.167两数之和 II - 输入有序数组 (so easy~) Leetcode.88合并两个有序数组 (还行) Leetcode.26删除有序数组中的重复项 (写的比我好) Leetcode.76最小覆盖子串 (不瞒说,再做一遍还是不会) Leetcode.32最长有效括号 (思路很牛逼,再做一遍还是不会)

滑动窗口、双指针、单调队列、单调栈_小名王能全的博客-爱代码爱编程

滑动窗口、双指针、单调队列、单调栈 LeetCode. 32 最长有效括号 括号序列合法 <=> 所有前缀和 >= 0 且 cnt == 0start: 当前枚举的这一段的开头cnt: 前缀和( = 1

acwing 154. 滑动窗口(单调队列)_2850g的博客-爱代码爱编程

题目描述 本题强推b站 董晓算法 老师的讲解,通俗易懂,我也是借鉴了里面许多关键思想。9.74 单调队列 滑动窗口最大值——信息学竞赛培训课程 分析: 滑动窗口可以先考虑暴力解,对长度为

leetcode 239. 滑动窗口最大值_ky0ma的博客-爱代码爱编程

做的第一个困难的题。 这题一上来很容易想到挨个求窗口的最大值来解决,但是那样会超时 正确解法是利用双队列来实现一个单调队列,只保存最大值和可能大的值 class Solution { public: class M

leetcode:滑动窗口、双指针、单调栈_给定一个整数数组,给定数字k,请计算使数组中所有小于k的整数相邻的最少交换次数。-爱代码爱编程

无重复字符的最长字串 3:给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。 class Solution { public int lengthOfLongestSubstring(String s) { if(s.length()==0) return 0; Has

acwing 79. 滑动窗口的最大值(c++)-爱代码爱编程

题目链接:https://www.acwing.com/problem/content/description/75/ 题目如下: class Solution { public: vector<int&g

单调队列(滑动窗口)_单调队列滑动窗口-爱代码爱编程

本质:大模拟(个人理解有错不要开骂哈) 单调队列性质: 1.内部元素大小单调递增or递减or在自己的规则内按合法顺序进行排列 2.内部元素在原序列中的次序必须单调递增 实现:使用双端队列(deque) 滑动窗口:多用来求一个序列区间中的最值 实现思路: 1.构造一个结构体单调队列,结构体成员分别为数字本身及其在原序列中的位置 2.确定窗口大

滑动窗口——单调队列(c/c++)_滑动窗口单调队列-爱代码爱编程

文章目录 一: 问题介绍二: 问题分析——分析最大值举例 1. 一般求解 2. 分析优化 三: 代码求解 1. 代码解析 2. 完整代码+运算结果 一: 问题介绍 二: 问