剑指offer刷题:栈和队列篇

文章目录

  • 一、用两个栈实现队列
    • 1.题目
    • 2.思路
    • 3.代码
  • 二、包含min函数的栈
    • 1.题目
    • 2.思路
    • 3.代码
  • 三、栈的压入、弹出序列
    • 1.题目
    • 2.思路
    • 3.代码

一、用两个栈实现队列

1.题目

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

2.思路

用两个栈push栈和pop栈来实现队列结构。

  1. 入队列的数永远进入push栈。出队列的数永远从pop栈出。
  2. 将push栈的数依次弹栈给pop栈。
  3. pop栈再依次取出,从而实现了队列结构。
    剑指offer刷题:栈和队列篇_第1张图片
    注:
  • 步骤2push栈一定要倒完。(不倒完队列会乱序)
  • 若pop栈非空,则一定不能进行步骤2。(pop栈非空也会造成乱序)

3.代码

import java.util.Stack;

public class Solution {
    Stack<Integer> sta_push = new Stack<Integer>();
    Stack<Integer> sta_pop = new Stack<Integer>();
    public void push(int node) {
        sta_push.push(node);
    }
    
    public int pop() {
        if(sta_pop.empty()){   //每次执行pop必须要把sta_pop倒干净 注释1
            while(!sta_push.empty()){
            sta_pop.push(sta_push.pop());
        } 
   }
        return sta_pop.pop();
    }
}

若不加注释1的代码
剑指offer刷题:栈和队列篇_第2张图片

二、包含min函数的栈

1.题目

定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))。

2.思路

再设置一个专门存放小值的sta_min栈。当发现新的小值时,sta和sta_min都入栈。出栈时,如果发现出栈的元素是一个小值,那么sta_min也要出栈。否则,sta_min不出栈,sta出栈。简之就是,大数的弹栈和sta_min无关。

3.代码

import java.util.Stack;

public class Solution {
    Stack<Integer> sta = new Stack<>();
    Stack<Integer> sta_min = new Stack<>();

    public Solution(){
        sta_min.push(Integer.MAX_VALUE);
    }
    public void push(int node) {
        sta.push(node);
        if(node <= sta_min.peek()){     //发现新的小结点,入min栈(一定要加等号)
            sta_min.push(node);
        }
    }

    public void pop() {
        if(sta.peek() == sta_min.peek()){   //这个判断控制了min栈不是每次都弹栈
            sta_min.pop();
        }
        sta.pop();
    }

    public int top() {
        return sta.peek();
    }

    public int min() {
        return sta_min.peek();
    }
}

三、栈的压入、弹出序列

1.题目

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

2.思路

  1. 借用一个辅助的栈,遍历压栈顺序,先讲第一个放入栈中。
  2. 然后判断栈顶元素是不是出栈顺序的第一个元素(即popA数组的第一个元素)。
  3. 若不等,则继续压栈。
  4. 直到相等以后开始出栈,出栈一个元素,则将出栈顺序向后移动一位,直到不相等。
  5. 这样循环,等压栈顺序遍历完成,如果辅助栈还不为空,说明弹出序列不是该栈的弹出顺序。

3.代码

import java.util.Stack;

public class Solution {
    public boolean IsPopOrder(int [] pushA,int [] popA) {
        if(pushA.length == 0 ){return false;}    //特殊情况
        Stack<Integer> sta = new Stack<>();
        sta.push(pushA[0]);                      //先压一个元素
        int j = 0;
        for(int i=0;i<pushA.length-1;){  //循环完后,pushA中每个元素都压栈过(不过有些可能压完弹栈了)
            if(sta.peek() == popA[j]){   //若栈顶元素和数组元素相等,则弹栈,数组右移
                sta.pop();
                j++;
            }                            //若栈顶元素和数组元素不等,则新元素压栈
            sta.push(pushA[++i]);
        }
        while(!sta.isEmpty() && j<pushA.length){ //剩下的数组元素和栈中剩下元素的弹栈顺序需要是一样的才能返回真
            if(sta.peek() == popA[j]){
                sta.pop();
                j++;
            }else{
                return false;
            }
        }
        return true;    
    }
}

你可能感兴趣的:(#,剑指offer刷题,队列,栈)