<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);
}
}