剑指offer-栈

面试题9:用两个栈实现队列 用两个队列实现栈

思路一:通用朴素型 画图
1.栈实现队列
把栈A当成主栈,栈B用于辅助。
入队: 将元素进栈A
出队: 先进先出,最先进来的,被压在最底下(栈底),因此把上面的元素挪开,放入栈B,直到栈A剩一个元素,pop它,最后再把元素挪回栈A。
2.队列实现栈
把队列A当成主队列,队列B用于辅助。
入栈: 将元素进队A
出栈: 后进先出,最后进来的,被压在最底下(队尾),因此把上面的元素挪开,放入队B,直到队A剩一个元素,pop它,最后再把元素挪回队A。

class Solution
{
public:
    void push(int node) {
        stack1.push(node);//把元素都放在栈A
    }

    int pop() {
        int a;
        int b;
        //如果栈A的元素个数大于1,就把A中元素出栈,放入栈B,直到栈A的元素个数为1
        if(stack1.size()!=1)
        {
            while(stack1.size()>1)
            {
                b = stack1.top();
                stack1.pop();
                stack2.push(b);
            }
        }
        //栈A中元素个数是1时,该元素就是要pop的
        a = stack1.top();
        stack1.pop(); 
        //再把栈B元素全都移回栈A
        while(!stack2.empty())
        {
          b = stack2.top();
          stack2.pop();
          stack1.push(b);
         }
      return a ;
  }

private:
    stack<int> stack1;
    stack<int> stack2;
};

思路二:改进思路一(挪动的过程,造成时间的浪费)
1.栈实现队列
挪到栈B后,可以不用挪回A,这时pop栈B,就是出队的顺序。
入队:将元素进栈A
出队:判断栈B是否为空,如果为空,则将栈A中所有元素pop,并push进栈B,栈B出栈; 如果不为空,栈B直接出栈。
2.队列实现栈
挪到队列B后,空的那个队列就变成了辅助队列。
入栈:将元素放入非空的队列
出栈:如果A是空的,把B中元素放到A,直到剩一个,pop;
如果B是空的,把A中元素放到B,直到剩一个,pop。

class Solution
{
public:
    void push(int node) {
        stack1.push(node);
    }

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

private:
    stack<int> stack1;
    stack<int> stack2;
};

面试题30 : 包含min函数的栈

定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数。
思路: 每次把最小的元素(之前的最小的元素和新压入栈的元素两者的较小值)都保存在辅助栈中。

class Solution {
public:
    void push(int value) {
        if(helpstack.empty())
        {
            helpstack.push(value);
        }
        else
        {
            int cmin = helpstack.top();
            if(value<cmin)
                helpstack.push(value);
            else
                helpstack.push(cmin);
        }
        numstack.push(value);
    }
    void pop() {
        numstack.pop();
        helpstack.pop();
    }
    int top() {
        return numstack.top();
    }
    int min() {
        return helpstack.top();
    }
private:
    stack<int> numstack;
    stack<int> helpstack;
};

面试题31 栈的压入、弹出序列

输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。

思路:
如果下一个弹出的数字刚好是栈顶数字,则直接弹出。
如果下一个弹出的数字不在栈顶,则把压栈序列还没入栈的数字压入栈,直到把下一个需要弹出的数字压入为止。
如果所有数字都压入栈后,仍没有找到下一个弹出的数字,那么该序列不可能是一个弹出的序列。

class Solution {
public:
    bool IsPopOrder(vector<int> pushV,vector<int> popV) {
        if(pushV.empty()||popV.empty()||pushV.size()!=popV.size())
            return false;
        stack <int> s;
        int j=0;
        for(int i = 0;i<pushV.size();i++)
        {
            s.push(pushV[i]);
            while(!s.empty()&&s.top()== popV[j])
            {
                s.pop();
                j++;
            }
        }
        if(s.empty())return true;
        else 
            return false;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值