1.3.3
假设某个用例程序会进行一系列入栈和出栈操作。入栈操作会将整数0到9按顺序压入栈;出栈操作会打印返回值。下面哪种顺序是不可能产生的?
(a) 4 3 2 1 0 9 8 7 6 5
(b) 4 6 8 7 5 3 2 9 0 1
(c) 2 5 6 7 4 8 9 3 1 0
(d) 4 3 2 1 0 5 6 7 8 9
(e) 1 2 3 4 5 6 9 8 7 0
(f) 0 4 6 5 3 8 1 7 2 9
(g) 1 4 7 9 8 6 5 3 0 2
(h) 2 1 4 3 6 5 8 7 9 0
方案一
分析:假设出入栈的就三个数 1,2,3,所有的情况数量是3的阶乘3!但仔细看其实其中一种情况是不满足的:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
即:3 1 2 是不可能的,首先输出3,说明1,2已经入栈,输出3后,2在栈顶,之后弹栈应该是2,所以这种情况不可能。
继而推广:“大 小 中 ”这种情况是不对的,由此可得选项中:(b)9 0 1、(f)8 1 7、 (g)3 0 2 这三种情况都是不可能出现的。
方案二
我们可以利用代码检测解决这个问题,既然这些序列(a,b...h)是从栈内输出的,那么建立一个辅助栈,将原来的0-9按照顺序入辅助栈,每次入栈时比较是否与待检测的序列元素(a,b...h)头节点相等,若相等则出栈,不相等则入栈,经过不断的入栈出栈,到最后辅助栈内应成为空栈,那么说明与要检测的序列对应上了,该序列合法,反之栈内留有元素则不合法。 那么咱们上代码:
/**
* 解决方案二(其实与下面方案三大同小异)
* 可以利用队列来或者用二维数组保存带检测的序列
* @param testQueue 待检测的队列
* @param originalQueue 原来将要入栈出栈等操作的队列
* @return
*/
public static boolean isValid(Queue<String> testQueue, Queue<String>originalQueue){
//检测序列是否合法
check(testQueue,originalQueue);
//利用队列来或者用二维数组保存带检测的序列
//建立辅助栈
Stack<String> stack = new Stack<>();
//当前数列与待检测序列分别用一个队列来保存,
Iterator<String> iterator = originalQueue.iterator();
while (iterator.hasNext()){
stack.push(iterator.next());
while (!stack.isEmpty()&&stack.top().equals( testQueue.peek())){
//出栈
stack.pop();
testQueue.dequeue();
}
}
return stack.isEmpty();
//test
public static void main(String[] args){
//"4 3 2 1 0 9 8 7 6 5";true
String str = "0 4 6 5 3 8 1 7 2 9";
String[] split = str.split("\s+");
Queue<String> queue = new Queue<>();
Queue<String> originalQueue = new Queue<>();
for (String s : split){
queue.enqueue(s);
}
for (int i = 0; i < 10;i++ ){
originalQueue.enqueue(""+i);
}
System.out.println(isValid(queue, originalQueue));
}
方案三
因为需要判断的这些序列都是从栈内输出的,所以如果逆序再进栈出栈 应该是可以得到9-0的顺序(其实就是上面那种翻着来的),但是这个方法写的仅使用于当前问题。 上代码:
public static boolean isValid(int[] seq)
{
Stack<Integer> stack = new Stack<Integer>();
int currentNum = 9;
int index = 9;
while (currentNum >= 0)
{
if (index >= 0 && seq[index] == currentNum)
{
index--;
currentNum--;
}
else if (!stack.isEmpty() && stack.top() == currentNum)
{
System.out.println(stack.pop());
currentNum--;
}
else
{
if (index < 0)
break;
stack.push(seq[index]);
index--;
}
}
return stack.isEmpty();
}
public static void main(String[] args)
{
while (!StdIn.isEmpty())
{
String line = StdIn.readLine();
String[] values = line.split("\\s+");
int[] nums = new int[10];
for (int i = 0; i < values.length; i++)
{
nums[i] = Integer.parseInt(values[i]);
}
if (isValid(nums))
{
System.out.println("OK");
}
else
{
System.out.println("No");
}
}
}