【deque】滑动窗口、双端队列解决数组问题

C++手册之deque

所属头文件 <deque>

常用操作:

back()返回尾部元素;

front()返回头部元素;

push_back()尾部插入元素;

pop_bakc()尾部删除元素;

push_front()头部插入元素;

pop_front()头部删除元素;



问题1:求滑动窗口的最大值(《剑指offer面试题65》)

描述:给定一个数组和滑动窗口的大小,找出所有滑动窗口里的最大值。

示例:数组{2, 3, 4, 2, 6, 2, 5} 窗口大小为 3,一共有7-3+1=5个滑动窗口,返回这些窗口最大值的数组{4, 4, 6, 6, 6}

方法:生成一个双端队列deque,里面存储可能成为滑动窗口最大值在数组中的下标

vector<int> getMax(const vector<int> &arr, int size){
    vector<int> res;
    if (arr.size() == 0 || size <= 0){
        return res;
    }
    deque<int> index;
    int i = 0;
    while (i < arr.size()){
        while (!index.empty() && arr[index.back()] <= arr[i]){
            index.pop_back();
        }
        index.push_back(i);
        if (!index.empty() && index.front() == (i - size)){
            index.pop_front();//不属于当前窗口
        }
        if (i >= size - 1){
            res.push_back(arr[index.front()]);
        }
        i++;
    }
    return res;
}


问题2:给定一个数组,找出最大值与最小值之差小于等于给定数num的子数组的个数。(牛客左程云《程序员面试代码指南》)

示例:给定数组{5, 2, 6, 3, 4, 1},num = 3,符合条件的子数组分别为{5} {5, 2} {2} {6} {6, 3} {6, 3, 4} {3} {3, 4} {3, 4, 1} {4} {4, 1} {1}返回数值12

方法:生成两个双端队列qmax, qmin,第一层while循环i,满足条件的将i作为起始元素的子数组;第二层while循环,满足条件的将j作为尾元素的子数组。每次内while循环结束,结果res += j - i;

qmax维护窗口子数组最大值在原数组中的下标;

qmin维护窗口子数组最小值在原数组中的下标。

窗口在动态发生变化,qmax和qmin的元素也在发生变化。

 1 int getNum(int arr[], int len, int num){
 2     if (arr == NULL || len < 1 ||num < 0)
 3         return 0;
 4     int res = 0;
 5     deque<int> qmax;
 6     deque<int> qmin;
 7     int i = 0;
 8     int j = 0;
 9     while (i < len){
10         while (j < len){
11             while (!qmax.empty() && arr[qmax.back()] <= arr[j]){
12                 qmax.pop_back();
13             }
14             qmax.push_back(j);
15             while (!qmin.empty() && arr[qmin.back()] >= arr[j]){
16                 qmin.pop_back();
17             }
18             qmin.push_back(j);
19             if (arr[qmax.front()] - arr[qmin.front()] > num){
20                 break;
21             }
22             j++; //j一直在变大,不回退
23         }
24         if (qmax.front() == i){
25             qmax.pop_front(); //不属于以i+1开头的窗口,弹出
26         }
27         if (qmin.front() == i){
28             qmin.pop_front(); //不属于以i+1开头的窗口,弹出
29         }
30         res += j - i;
31         i++; //i一直在变大,不回退
32     }
33     return res;
34 }
时间: 2025-01-13 09:09:16

【deque】滑动窗口、双端队列解决数组问题的相关文章

关于双端队列 deque 模板 &amp;&amp; 滑动窗口 (自出)

嗯... deque 即为双端队列,是c++语言中STL库中提供的一个东西,其功能比队列更强大,可以从队列的头与尾进行操作... 但是它的操作与队列十分相似,详见代码1: 1 #include <cstdio> 2 #include <iostream> 3 #include <deque> 4 //实际上,引用queue头文件也可以,里面包含了deque头文件 5 6 using namespace std; 7 8 deque<int> dq; //定义

队列的应用:双端队列

双端队列(Deque:double ended queue)就是一个两端都是结尾的队列.队列的每一端都可以插入数据项和移除数据项.相对于普通队列,双端队列的入队和出队操作在两端都可进行. 双端队列的示意图: left:左端    right:右端 这里我们使用最常用的顺序结构来存储双端队列,为了节省空间,把它首尾相连,构成循环队列.并且规定left指向左端的第一个元素,right指向右端的下一个位置.那么队空的判断则是left==right,队满是(left-1+MAX)%MAX==right或

列表VS双端队列

双端队列支持线程安全,在两端任何一端执行添加和删除,时间复杂度为o(1).访问两端的索引访问,时间复杂度为o(1).访问中间元素时间复杂度为o(n).随机访问还是采用列表 列表:时间复杂度为o(n) 双端队列的实现:class Deque:# 模拟双端队列def __init__(self):self.items = []def isEmpty(self):return self.items == []def addFront(self,item):self.items.append(item)

deque双端队列容器(对象创建,数组、迭代器方式访问,元素的赋值、插入、删除等)

deque与vector非常相似,不仅可以在尾部插入和删除元素,还可以在头部插入和删除.不过当考虑到容器元素的内存分配策略和操作性能时,deque相对vector较为有优势. 头文件 #include<deque> 创建deque对象 1)deque();//创建一个没有任何元素的deque对象. deque<int> d 2)deque(size_typen);//创建一个具有n个元素的deque对象,每个元素采用它的类型下的默认值. deque<int> d(10)

[程序员代码面试指南]栈和队列-生成窗口最大值数组(双端队列)

问题描述 输入数组arr={4,3,5,4,3,3,6,7},窗口大小w=3,窗口由左向右移动,输出每个窗口最大值组成的数组. 解题思路 数据结构:使用ArrayList模拟双端队列. 遍历一遍arr,时间复杂度O(n).具体地, 队列队尾的位置对应的元素若不比当前位置对应元素大,则弹出,否则,将当前元素入队. -每次检查队首元素下标是否已超出以当前位置为结尾的窗口,超出则出队. 代码 import java.util.LinkedList; public class Main { public

nyoj1117 鸡蛋队列 (双端队列,deque)

题目1117 题目信息 运行结果 本题排行 讨论区 鸡蛋队列 时间限制:1000 ms  |  内存限制:65535 KB 难度:1 描述 将两根筷子平行的放在一起,就构成了一个队列.将带有编号的鸡蛋放到两根筷子之间叫做入队(push),将筷子之间的鸡蛋拿出来叫做出队(pop).但这两种方式有特殊的定义,对于入队,只能将鸡蛋从队列的尾部向里放入:对于出队,只能将鸡蛋从队列的头部向外将鸡蛋拿出来. 将①.②入队: 头____________尾                         ___

stl之deque双端队列容器

deque与vector很相似,不仅能够在尾部插入和删除元素,还能够在头部插入和删除. 只是当考虑到容器元素的内存分配策略和操作性能时.deque相对vector较为有优势. 头文件 #include<deque> 创建deque对象 1)deque();//创建一个没有不论什么元素的deque对象. deque<int> d 2)deque(size_typen);//创建一个具有n个元素的deque对象.每一个元素採用它的类型下的默认值. deque<int> d(

URAL 2026 Dean and Schedule 贪心、双端队列(deque)、队列(queue)

C - Dean and Schedule Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Practice URAL 2026 Description A new academic year approaches, and the dean must make a schedule of classes for first-year students. Ther

std::deque双端队列介绍

在建立vector容器时,一般来说伴随这建立空间->填充数据->重建更大空间->复制原空间数据->删除原空间->添加新数据,如此反复,保证vector始终是一块独立的连续内存空间:在建立deque容器时,一般便随着建立空间->建立数据->建立新空间->填充新数据,如此反复,没有原空间数据的复制和删除过程,是由多个连续的内存空间组成的. C++ STL容器deque和vector很类似,也是采用动态数组来管理元素. 与vector不同的是deque的动态数组首