【牛客剑指offer】数据结构——队列&栈

JZ9 用两个栈实现队列

代码

    void push(int node) {
        stack1.push(node);
    }

    int pop() {
        int res = -1;
        if (stack2.empty()) {
            //入队栈弹出 进入出队栈
            if (stack1.empty()) {
                return -1;
            } else
                while (!stack1.empty()) {
                    stack2.push(stack1.top());
                    stack1.pop();
                }
        }
        res = stack2.top();
        stack2.pop();
        return res;
    }

get

讲解视频
思路:
两个栈一个用作push,一个用作pop
入队——直接插入push栈,在栈顶
出队——
先判断pop栈有无元素可出。
pop栈空时,判断push栈有无元素,若无,两栈均无元素可用于弹出,即队空无法出队,返回-1;若push栈非空,将push栈中所有元素压入pop栈;
pop栈非空(本身非空,或判断后进行上述操作push栈有元素进入导致非空),弹出栈顶元素并返回。

JZ20包含min元素的栈

代码

    //用于栈的push 与 pop
    stack<int> s1;
    //用于存储最小min
    stack<int> s2;
    void push(int value) {
        s1.push(value);
        //空或者新元素较小,则入栈
        if (s2.empty() || s2.top() > value)
            s2.push(value);
        else
            //重复加入栈顶
            s2.push(s2.top());
    }
    void pop() {
        s1.pop();
        s2.pop();
    }
    int top() {
        return s1.top();
    }
    int min() {
        return s2.top();
    }
};

get

s1保存栈中元素,s2为辅助栈,保存s1中从栈底截至各个元素,这一段元素中的最小元素。
入栈时压入s1,s2为空或者s2栈顶元素(即入栈前s1中的最小元素)更大,则表示新入栈的元素比s1之前的元素都要小,最小元素变化,新元素压入s2.
出栈时s1、2同步出栈

注意到判断条件s2.empty() || s2.top() > value不可修改顺序,否则会出错。
在这里插入图片描述

栈的压入、弹出序列

代码

    bool IsPopOrder(vector<int> pushV, vector<int> popV) {
        if (pushV.empty() || pushV.size() == 0) {
            return true;
        }
        stack<int> s;
        int iPush = 0;
        int iPop = 0;
        int lenPush = popV.size();
        for (; iPush < lenPush; iPush++) {
            s.push(pushV[iPush]);
            while ((!s.empty()) && s.top() == popV[iPop]) {
                iPop++;
                s.pop();
            }
        }
        int lenPop = popV.size();
        for (; iPop < lenPop; iPop++) {
            while ((!s.empty()) && s.top() == popV[iPop]) {
                iPop++;
                s.pop();
            }
        }
        return s.empty();
    }

get

压入序列,弹出序列,辅助栈
压入序列压入辅助栈。
比较栈顶与弹出序列的第一个弹出元素,若相同则弹出栈顶、弹出序列位序后移,继续比较当前栈顶和当前弹出元素。
若不同,压入序列压入辅助栈,继续上述操作。
可能存在压入序列全部入栈,而出栈序列未处理完的情况,再次使用一个for循环处理弹出序列,与辅助栈中元素进行比对,处理如上。
若比较完毕弹出序列后,辅助栈空,则表示按照入栈顺序入栈,按照弹出序列弹出,可将辅助栈中元素全部弹出,即辅助栈中元素按照弹出序列可完全弹出,则返回true
否则返回false
返回值由辅助栈是否为空决定。

反转单词序列

代码

    string ReverseSentence(string str) {
        int n=str.length();

        reverse(str.begin(), str.end());
        for(int i=0; i<n; i++){
            int j=i;
            while(j<n && str[j]!=' ')
                j++;
            reverse(str.begin()+i, str.begin()+j);
            i=j;
        }
        return str;
    }

get

单词拼写是正序,单词排序是逆序,各个单词之间用空格分开。
使用逆置函数reverse。
首先全部逆置,得到正确的单词顺序,但单词拼写是逆序的。
通过空格区分单词,单词内部拼写逆置。

滑动窗口的最大值

代码

    vector<int> maxInWindows(const vector<int>& num, unsigned int size) {
        vector<int> res ;
        if (num.empty() || num.size() == 0 || size == 0 || num.size() < size) {
            return res;
        }
        for (int i = 0; i <= num.size() - size; i++) {
            int cur=0;
            for (int j = i; j < i+size; j++) {
                    cur = max(num[j], cur);
                }
            res.push_back(cur);
        }
        return res;
    }

get

暴力解法
先处理需要返回空的情况
找滑动窗口中的最大值,i确定滑动窗口的起点,j为滑动窗口中正在处理的最后位置,cur为i~j中的最大元素。滑动窗口中所有的处理完后,cur归入结果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值