剑指Offer-->栈的压入、弹出序列(★★★★★)

<strong><span style="font-size:18px;">   <span style="font-family:KaiTi_GB2312;">栈的难度不大,但是在剑指Offer中很多题目涉及到此,其中的难度我觉得也没有很简单,为了要通过牛客网的编译还真是不简单,要考虑的东西还是蛮多的。。。毕竟要通过所有的测试用例。此题:栈的压入与弹出序列,对栈的应用我觉得还是很全面的,是一个非常不错的题目。其中部分代码也有所解释~</span></span></strong>


package T19;

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

/**
 * Created by zhangshuyou on 2015/5/20.
 */

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

/**
 * 此题难度自我感觉还是比较大的=。=
 * 其中需要特别特别特别注意的有两点(之前不晓得。。)
 * 1.null 和 isEmpty()的区别
 *   null是指对象本身没分配内存,isEmpty()是指这个对象指向的内存单元中没有数据
 * 2.当栈为空时,是不可以对栈进行peek()操作的,会报异常。
 *
 * 解题思路:当对题目感觉毫无头绪的时候,举个例子,可能会使思路更加清晰,一个正例一个反例即可。
 * 由于我们要先找到pushA中和popA中相等的元素,而此数之前的元素需要后来再操作,这种先进后出的规则让我们想到了栈~
 * 第一个序列的数字压入辅助栈,并按第二个序列的数字弹出辅助栈
 * eg:pushA的顺序为12345 popA的顺序为45321
 * 1.第一个希望弹出的数字是4,因此4要先放在辅助栈里。压入栈的顺序由pushA决定,在放4之前,先将123依次入栈。
 * 2.此时栈中含有4个元素,4位于栈顶,正好弹出,此时还有123
 * 3.接下来希望弹出5,不是栈顶数字,把pushA中4以后的数字压入栈,直到5,当5位于栈顶,就弹出。
 * 4.剩下的元素每次都位于栈顶,依次弹出即可
*/
public class Solution {

    public boolean IsPopOrder(ArrayList<Integer> pushA , ArrayList<Integer> popA) {
        Stack<Integer> stack = new Stack<Integer>();  //加入一个辅助栈
        /*if(pushA.isEmpty() || popA.isEmpty())  //其中一个为空,返回false  这种写法在牛客网上无法通过
            return false;*/
        if(pushA == null || popA == null)  //其中一个为空,返回false
            return false;
        int P1 = 0; //设定一个指针,找到pushA中的元素并自增入栈
        for(int i = 0;i < popA.size();i++){
            //当栈不为空,且栈顶元素等于popA中得到的元素便出栈
            if(!stack.isEmpty() && stack.peek() == popA.get(i))
                stack.pop();
            else {
                if (P1 == pushA.size())
                    return false;
                else {
                    //当popA的头元素不等于stack的头元素,就将pushA的元素依次压入辅助栈
                    //且注意一点,当栈为空时,不能使用peek()方法,因此必须在做判断之前,先在栈中加入数据,此处用到了do...while方法来实现
                    do {
                        stack.push(pushA.get(P1++));
                    } while (stack.peek() != popA.get(i) && P1 != pushA.size());

                    //此时便可以得到popA中的头元素与辅助栈中头元素相等的值,当二者相等,进行出栈操作;当找不到相等的元素,返回false
                    if (stack.peek() == popA.get(i)) {
                        stack.pop();
                    } else {
                        return false;
                    }
                }
            }
        }
        return true;
}

public static void main(String[] args) {
    // 进栈序列
    ArrayList<Integer> list1 = new ArrayList<Integer>();
    list1.add(1);
    list1.add(2);
    list1.add(3);
    list1.add(4);
    list1.add(5);
    // 出栈序列
    ArrayList<Integer> list2 = new ArrayList<Integer>();
    list2.add(4);
    list2.add(3);
    list2.add(5);
    list2.add(1);
    list2.add(2);
    //{6,4, 3, 5, 2, 1 };//{ 4, 3, 5, 2, 1 };
    boolean flag = new Solution().IsPopOrder(list1, list2);
    System.out.println(flag);
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值