剑指offer:滑动窗口的最大值(栈和队列)

1. 题目描述

/*
    给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。
    例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5};
    针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个:  {[2,3,4],2,6,2,5,1},   {2,[3,4,2],6,2,5,1},   {2,3,[4,2,6],2,5,1},   {2,3,4,[2,6,2],5,1},   {2,3,4,2,[6,2,5],1},   {2,3,4,2,6,[2,5,1]}。
*/

2. 思路

/**
 * 题目:滑动窗口的最大值
 * 思路:滑动窗口应当是队列,但为了得到滑动窗口的最大值,队列序可以从两端删除元素,因此使用双端队列。
 * 原则:
 *     对新来的元素c,将其与双端队列中的元素相比较
 *     1)后面(队列的尾部)比c小的x,直接移出队列(因为不再可能成为后面滑动窗口的最大值了!);
 *     2)前面(队列的头部)比c大的X,比较两者下标,判断X是否已不在窗口之内,不在了,直接移出队列;
 *     3)队列的第一个元素是滑动窗口中的最大值。
 */

3. 代码

import java.util.*;
public class Solution {
    public ArrayList<Integer> maxInWindows(int [] num, int size) {
        if (num == null || num.length == 0 || size <= 0 || num.length < size) {
            return new ArrayList<Integer>();
        }
        ArrayList<Integer> result = new ArrayList<>();
        //双端队列,用来记录每个窗口的最大值下标
        LinkedList<Integer> qmax = new LinkedList<>();
        int index = 0;
        for (int i = 0; i < num.length; i++) {
            //若队列不为空且 队列最后一个元素<当前值, 因为它不再可能成为后面滑动窗口的最大值了
            while (!qmax.isEmpty() && num[qmax.peekLast()] < num[i]) {
                qmax.pollLast();
            }
            qmax.addLast(i);
            //判断队首元素是否过期
            while (qmax.peekFirst() <= i - size) {
                qmax.pollFirst();
            }
            //上面两个while保证了了队列头部第一个元素是每一个窗口的最大值
            //保存每一个窗口的最大值(注意:从size-1开始)
            if (i >= size - 1) {
                result.add(num[qmax.peekFirst()]);
            }
        }
        return result;
    }
}

原文地址:https://www.cnblogs.com/haimishasha/p/11520681.html

时间: 2024-08-03 03:27:07

剑指offer:滑动窗口的最大值(栈和队列)的相关文章

剑指offer 滑动窗口的最大值

题目描述 给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值.例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5}: 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个: {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1}, {2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,

剑指OFFER之用两个栈实现队列(九度OJ1512)

题目描述: 用两个栈来实现一个队列,完成队列的Push和Pop操作.队列中的元素为int类型. 输入: 每个输入文件包含一个测试样例.对于每个测试样例,第一行输入一个n(1<=n<=100000),代表队列操作的个数.接下来的n行,每行输入一个队列操作:1. PUSH X 向队列中push一个整数x(x>=0)2. POP 从队列中pop一个数. 输出: 对应每个测试案例,打印所有pop操作中从队列pop中的数字.如果执行pop操作时,队列为空,则打印-1 样例输入: 3 PUSH 10

[剑指Offer]9.用两个栈实现队列

题目 用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型. 思路 用栈来模拟队列.我们首先插入一个元素a到stack1中,再压入两个元素bc,此时栈中有元素abc,其中c位于栈顶,而stack2仍然为空.我们试着删除一个元素.按照队列先进先出的原则,我们应该先删除元素a.元素a存放在stack1中且不在栈顶,因此不能直接删除.注意到stack2还未使用,我们把stack1中的元素逐个弹出并压入stack2中,stack2中的元素是cba,栈顶元素是a,我们现在可以

【Java】 剑指offer(8) 用两个栈实现队列

本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集  题目 用两个栈实现一个队列.队列的声明如下,请实现它的两个函数appendTail和deleteHead,分别完成在队列尾部插入结点和在队列头部删除结点的功能. 思路 这道题较简单,自己先试着模拟一下插入删除的过程(在草稿纸上动手画一下):插入肯定是往一个栈stack1中一直插入:删除时,直接出栈无法实现队列的先进先出规则,这时需要将元素从stack1出栈,压到另一个栈stack2

剑指offer系列-用两个栈实现队列

oj地址 题目1512:用两个栈实现队列 时间限制:1 秒 内存限制:128 兆 特殊判题:否 提交:2360 解决:804 题目描述: 用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型. 输入: 每个输入文件包含一个测试样例. 对于每个测试样例,第一行输入一个n(1<=n<=100000),代表队列操作的个数. 接下来的n行,每行输入一个队列操作: 1. PUSH X 向队列中push一个整数x(x>=0) 2. POP 从队列中pop一个数. 输出:

剑指OFFER之用两个栈实现队列

题目描述: 用两个栈来实现一个队列,完成队列的Push和Pop操作.队列中的元素为int类型. 输入: 每个输入文件包含一个测试样例.对于每个测试样例,第一行输入一个n(1<=n<=100000),代表队列操作的个数.接下来的n行,每行输入一个队列操作:1. PUSH X 向队列中push一个整数x(x>=0)2. POP 从队列中pop一个数. 输出: 对应每个测试案例,打印所有pop操作中从队列pop中的数字.如果执行pop操作时,队列为空,则打印-1. 样例输入: 3 PUSH 1

【剑指Offer】用两个栈实现队列

问题描述: 用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型. 算法分析: push: 1.将数据压入stack1: pop: 1.将stack1中所有数据弹出到stack2: 2.将stack2中第一个数弹出设置为返回值: 3.将stack2中所有数据弹出到stack1: 4.将返回值返回 代码实现 class Solution { public: void push(int node) { stack1.push(node); } int pop() { w

剑指offer:用两个栈实现队列

题目:用两个栈实现一个队列.请实现它的两个函数appendTail和deleteHead,分别完成在队列尾部插入节点和在队列头部删除结点的功能.队列的声明如下: template <typename T> class CQueue { public: CQueue(void); ~CQueue(void); // 在队列末尾添加一个结点 void appendTail(const T& node); // 删除队列的头结点 T deleteHead(); private: stack&

剑指offer T5 用两个栈实现队列

调用push时往stack1中添加元素,调用pop时,将stack1中的元素全部弹出压入stack2,然后再从stack2栈顶取元素 原文地址:https://www.cnblogs.com/jiguang321/p/11578385.html

剑指Offer--065-滑动窗口的最大值

1 链接 牛客OJ:滑动窗口的最大值 九度OJ:未收录 GitHub代码: 065-滑动窗口的最大值 CSDN题解:剑指Offer–065-滑动窗口的最大值 | 牛客OJ | 九度OJ | CSDN题解 | GitHub代码 | | --- |:---:|:---:| ---:| 065-滑动窗口的最大值 2 题意 题目描述 题目描述 给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值 例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3 那么一共存在6个滑动窗口,