剑指Offer-栈的压入弹出序列

题目描述

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

题目解析

题目中要求一个序列是不是另一个序列出栈的诸多顺序中的一种,我一开始想法是先找规律,看看是不是这个顺序是不是有些固定的逻辑可以用于判断违反了规则而直接返回false的情况,但是很遗憾,没有并没有找到一个通过串的顺序来判断的规律,可能是有的,只是我在短时间内无法发现而已。


解题思路

这个题目可以直接采用辅助的一个栈的结构来暂时存储数据,模拟栈的出栈操作,如果说栈顶和出栈的这个串的当前索引下的数据是一致的那么将已经入栈的数据出栈,如果不一样的话,就不断的入栈,直到所有数据都入栈,这个时候的数据要么栈数据已经为空了,要么就是栈中没有空,没有空的话,就开始出栈,并且把栈顶的数据和出栈序列的对应的索引的数据进行比对,如果一致那就继续出栈,出栈序列的索引指向下一个元素。一直到栈为空都不存在不一样的数据的话,那么就说明该序列是对的,否则直接返回false。


代码实现

import java.util.ArrayList;

public class Solution {
    ArrayList<Integer> stack = new ArrayList<Integer>();
    
    public boolean IsPopOrder(int [] pushA,int [] popA) {
      
        int outIndex = 0;
        
        for(int i = 0; i < pushA.length; i ++) {
            
            stack.add(pushA[i]); 
            
            if(stack.get(stack.size() - 1) == popA[outIndex]) {
                
                outIndex ++;
                stack.remove(stack.size()-1);
            }
            
        }
        
        for(int j = stack.size() - 1; j >= 0; j --) {
            
            if(!(stack.get(j) == popA[outIndex])) {
                return false;
            }
            outIndex ++;
        }
        return true;
    }
}

附录

另外的一种实现

这种实现的思路主要是,尽可能在遍历完成一遍以后将整个串已经匹配完,如果未匹配完的话就说明这个串是错误的出栈顺序,遍历过程中通过while循环的方式不断的判断是不是存在匹配的子串,存在就将该子串出栈,直到结束。

链接:https://www.nowcoder.com/questionTerminal/d77d11405cc7470d82554cb392585106

import java.util.*;
 
public class Solution {
    public boolean IsPopOrder(int [] pushA,int [] popA) {
      Stack<Integer> s = new Stack<>();
      int i = 0;
      for(int a: pushA)
      {
          s.push(a);
          while(!s.isEmpty() && s.peek() == popA[i])
          {
              s.pop();
              i++;
          }
      }
      if(s.isEmpty()) return true;
      return false;
    }
}




评论 26
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值