单调栈、单调队列

简介: 单调栈、单调队列

java中对栈进行了包装,即new Stack()


把元素入栈:push(E);把栈顶的元素“弹出”:pop();取栈顶元素但不弹出:peek() (栈为空时抛异常)判断栈是否为空:isEmpty()


单调栈例题


https://www.acwing.com/problem/content/832/

import java.util.*;
public class Main {
    public static void main(String[] args)  {
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();
        int []arr=new int[n];
        for (int i = 0; i < n; i++) {
            arr[i]= sc.nextInt();
        }
        //存储最后的结果
        StringBuilder sb=new StringBuilder();
        //new 一个栈出来
        Stack<Integer> stack=new Stack<>();
        for (int i : arr) {
            //stack.peek() 取栈顶元素但不弹出
            while (!stack.empty() &&i<=stack.peek()) {
                //stack.pop() 把栈顶的元素“弹出”
                stack.pop();
            }
            if(stack.empty()){
                sb.append("-1 ");
            }else sb.append(stack.peek()+" ");
            //元素入栈
            stack.push(i);
        }
        System.out.println(sb.toString());
    }
}


单调队列例题 滑动窗口


https://www.acwing.com/problem/content/156/

思路

利用单调队列解决问题


题目要求求出滑动窗口范围内所有的最大最小值,而且滑动窗口中数的操作也符合队列的性质,右移一位,队头出,队尾加,这正好符合单调队列的所有性质,单调队列的头部会保存当前窗口中的最小或者最大值。

本题数据模拟

q1单调递增队列 q2单调递减队列


窗口位置 队列q1 队列q2 最小值(q1队头) 最大值(q2队头)

[1 3 -1] -3 5 3 6 7 [2] [1, 2] a[2] = -1 a[1] = 3

1 [3 -1 -3] 5 3 6 7 [3] [1, 2, 3] a[3] = -3 a[1] = 3

1 3 [-1 -3 5] 3 6 7 [3, 4] [4] a[3] = -3 a[4] = 5

1 3 -1 [-3 5 3] 6 7 [3, 5] [4, 5] a[3] = -3 a[4] = 5

1 3 -1 -3 [5 3 6] 7 [5, 6] [6] a[5] = 3 a[6] = 6

1 3 -1 -3 5 [3 6 7] [5,6,7] [7] a[5] = 3 a[7] = 7


import java.io.*;
public class Main {
    static int N=1000010;
    static int[]arr=new int[N];
    static int[]q=new int[N];
    static int hh=0,tt=-1;
    public static void main(String[] args) throws IOException {
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(System.out));
        String []s=br.readLine().split(" ");
        int n=Integer.parseInt(s[0]),k=Integer.parseInt(s[1]);
        String []s1=br.readLine().split(" ");
        for (int i = 0; i < n; i++) {
            arr[i]=Integer.parseInt(s1[i]);
        }
        for (int i = 0; i < n; i++) {
            // 判断队头是否已经滑出窗口, 如果滑出窗口, 则弹出队首元素,维护窗口大小不超过 k, 每次值滑动一次, 所以可以使用 if
            if (hh<=tt && i-k+1>q[hh]) hh++;
            //寻找窗口最小值
            while (hh<=tt &&arr[q[tt]]>=arr[i]) tt--;
            q[++tt]=i;
            if(i+1>=k) bw.write(arr[q[hh]]+" ");
        }
       bw.write("\n");
        hh=0; tt=-1;
        for (int i = 0; i < n; i++) {
            if (hh<=tt && i-k+1>q[hh]) hh++;
            //寻找窗口最大值
            while (hh<=tt &&arr[q[tt]]<=arr[i]) tt--;
            q[++tt]=i;
            if(i+1>=k) bw.write(arr[q[hh]]+" ");
        }
        bw.flush();
        br.close();
        bw.close();
    }
}


相关文章
|
2天前
|
存储 算法 搜索推荐
探索常见数据结构:数组、链表、栈、队列、树和图
探索常见数据结构:数组、链表、栈、队列、树和图
76 64
|
10天前
|
算法 安全 测试技术
golang 栈数据结构的实现和应用
本文详细介绍了“栈”这一数据结构的特点,并用Golang实现栈。栈是一种FILO(First In Last Out,即先进后出或后进先出)的数据结构。文章展示了如何用slice和链表来实现栈,并通过golang benchmark测试了二者的性能差异。此外,还提供了几个使用栈结构解决的实际算法问题示例,如有效的括号匹配等。
golang 栈数据结构的实现和应用
|
2天前
|
Go
数据结构之 - 深入了解栈数据结构
数据结构之 - 深入了解栈数据结构
11 5
|
11天前
|
前端开发
07_用队列实现栈
07_用队列实现栈
|
11天前
06_用栈来求解汉诺塔问题
06_用栈来求解汉诺塔问题
|
11天前
05_用一个栈实现另一个栈的排序
05_用一个栈实现另一个栈的排序
|
2天前
|
存储
【初阶数据结构】深入解析栈:探索底层逻辑
【初阶数据结构】深入解析栈:探索底层逻辑
|
11天前
01_设计一个有getMin功能的栈
01_设计一个有getMin功能的栈
|
11天前
03_如何仅用递归函数和栈操作逆序一个栈
03_如何仅用递归函数和栈操作逆序一个栈
|
11天前
|
测试技术
02_由两个栈组成的队列
02_由两个栈组成的队列