bj_剑指offer——栈与队列

用两个栈实现队列

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

题解:
队列:先进先出
栈:先进后出

当我们向模拟的队列插入数 a,b,c 时,假设插入的是 stack1,此时的栈情况为:

栈 stack1:{a,b,c}
栈 stack2:{}
当需要弹出一个数,根据队列的"先进先出"原则,a 先进入,则 a 应该先弹出。但是此时 a 在 stack1 的最下面,将 stack1 中全部元素逐个弹出压入 stack2,现在可以正确的从 stack2 中弹出 a,此时的栈情况为:

栈 stack1:{}
栈 stack2:{c,b}
继续弹出一个数,b 比 c 先进入"队列",b 弹出,注意此时 b 在 stack2 的栈顶,可直接弹出,此时的栈情况为:

栈 stack1:{}
栈 stack2:{c}
此时向模拟队列插入一个数 d,还是插入 stack1,此时的栈情况为:

栈 stack1:{d}
栈 stack2:{c}
弹出一个数,c 比 d 先进入,c 弹出,注意此时 c 在 stack2 的栈顶,可直接弹出,此时的栈情况为:

栈 stack1:{d}
栈 stack2:{c}
根据上述栗子可得出结论:

当插入时,直接插入 stack1
当弹出时,当 stack2 不为空,弹出 stack2 栈顶元素,如果 stack2 为空,将 stack1 中的全部数逐个出栈入栈 stack2,再弹出 stack2 栈顶元素

import java.util.Stack;

public class Solution {
    Stack<Integer> stack1 = new Stack<Integer>();
    Stack<Integer> stack2 = new Stack<Integer>();
    
    public void push(int node) {
        stack1.push(node);
    }
    
    public int pop() {
        if(stack2.size()<=0){
            while(stack1.size()!=0){
                stack2.push(stack1.pop());
            }
        }
        return stack2.pop();
    }
}

包含min函数的栈

题目描述
定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))。
注意:保证测试中不会当栈为空的时候,对栈调用pop()或者min()或者top()方法。

题解:
用两个栈实现。
用一个栈stack保存数据,用另外一个栈min保存依次入栈最小的数  
//peek 不改变栈的值(不删除栈顶的值),pop会把栈顶的值删除。

import java.util.Stack;

public class Solution {
/* 
* 思路:用一个栈stack保存数据,用另外一个栈min保存依次入栈最小的数  
* 比如,stack中依次入栈,5, 4, 3, 8, 10,11,12,1  
* 则min依次入栈,5, 4, 3, 3, 3, 3, 3, 1 
* 每次入栈的时候,如果入栈的元素比min中的栈顶元素小或等于则入栈,否则入stack的栈顶元素。  
* 保持stack中和min中保持相同个数的元素 ,同时保持min的栈顶是此时原栈的最小值。
*/
    Stack<Integer> stackData = new Stack<>();
    Stack<Integer> stackMin = new Stack<>();
    
    public void push(int node) {
        stackData.push(node);
        if(stackMin.isEmpty()||stackMin.peek()>node){
            stackMin.push(node);
        }else
            stackMin.push(stackMin.peek());
    }
    
    public void pop() {
        if(!stackData.isEmpty()){
            stackData.pop();
            stackMin.pop();
        }
    }
    
    public int top() {
        return stackData.peek();
    }
    
    public int min() {
        return stackMin.peek();
    }
}

栈的压入、弹出序列

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

题解:

借用一个辅助的栈,遍历压栈顺序,先讲第一个放入栈中,这里是1,然后判断栈顶元素是不是出栈顺序的第一个元素,这里是4,很显然14,所以我们继续压栈,直到相等以后开始出栈,出栈一个元素,则将出栈顺序向后移动一位,直到不相等,这样循环等压栈顺序遍历完成,如果辅助栈还不为空,说明弹出序列不是该栈的弹出顺序。
举例:
入栈1,2,3,4,5
出栈4,5,3,2,1
首先1入辅助栈,此时栈顶14,继续入栈2
此时栈顶24,继续入栈3
此时栈顶34,继续入栈4
此时栈顶44,出栈4,弹出序列向后一位,此时为5,辅助栈里面是1,2,3
此时栈顶35,继续入栈5
此时栈顶5=5,出栈5,弹出序列向后一位,此时为3,辅助栈里面是1,2,3将第一个数组遍历压入pushA
如果popA[]到最后一位时,恰好辅助栈弹出所有元素变为空,则说明弹出序列是该栈的弹出顺序。否则,不是。

import java.util.ArrayList;
import java.util.Stack;

public class Solution {
    public boolean IsPopOrder(int [] pushA,int [] popA) {
        if(pushA.length==0||popA.length==0||pushA.length!=popA.length){
            return false;
        }
        int j=0;
        Stack<Integer> st = new Stack<>();
        for(int i=0;i<pushA.length;i++){
            st.push(pushA[i]);
            while(st.peek()==popA[j]){
                if(st.size()>=1){
                    st.pop();
                    j++;
                     if(st.isEmpty()){
                        return true;
                     }
                }
            }
        }
        return false;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值