剑指offer刷题记录——栈和队列

用两个栈实现队列

题目描述

用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。

实现思路

比较基础,知道队列为先进先出,栈为先进后出即可。用一个栈存储队列元素,另一个栈辅助实现队列的出队操作。以下我的做法比较直观也比较麻烦,至始至终有stack1存储元素,其实可以根据队列先进先出的特点,由stack2保存部分元素。

具体实现

    int pop() {
        int cur;
        while(!stack1.empty()){
            cur = stack1.top();
            stack2.push(cur);
            stack1.pop();
        }
        int res = stack2.top();
        stack2.pop();
        
        while(!stack2.empty()){
            cur = stack2.top();
            stack1.push(cur);
            stack2.pop();
        }
        return res;
        
    }

 

滑动窗口的最大值

题目描述

给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{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]}。

实现思路

题目很直观,显然直接求解的话也很简单,但考虑到直接求解的话会有冗余的过程,这样的程序显然是不合格的。
其实很清楚的是,每次滑动只需判断一下上一个窗口的最大值是否过期,能否继续使用。这个过程用双端队列来模拟最合适了。
用队列头部表示当前窗口最大值的索引(为什么是索引而不是数呢,因为索引可以帮助我们判断是否过期这个问题)。对每一个新增加的数,从队尾开始比较,将所有比它小的数丢掉(出现的时间比他早还比他小,不丢掉干嘛?)。
然后再判断当前队列头部的索引是否在该窗口范围内,若在的话就丢掉。

具体实现


class Solution {
public:
    vector<int> maxInWindows(const vector<int>& num, unsigned int size)
    {
        vector<int> res;
        deque<int> q;
        for(int i=0;i<num.size();i++){
            //
            while(q.size()&&num[q.back()]<=num[i]){
                q.pop_back();
            }
            if(q.size()&&i-q.front()>=size){
                q.pop_front();
            }
            q.push_back(i);
            if(size&&i+1>=size)
                res.push_back(num[q.front()]);
        }
        return res;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值