栈的可能行。用例程序会进行一系列混合的入栈出栈操作,入栈操作按0,1,…,N-1的顺序进行,判断给定的排列是否是某系列混合出入栈操作的结果(你使用的空间量与N无关,即不能用某种数据结构存储所有整数)。
书中的提示:除非对于某个整数k,前k次出栈操作会在前k次入栈操作前完成,否则栈不会向下溢出。如果某个排列可以产生,那么它产生的方式一定是唯一的:如果输出排列中的下一个整数在栈顶,则将它弹出,否则将它压入栈中。而我设计的算法无需考虑(未考虑)下溢出的情况,可能有隐藏的错误。
思路a:设给定的乱序排列为(参考)栈refer,顺序排列为(输入)栈in,为即使出栈的整数被存储在栈buffer。成功出栈次数为printNum,打印结果为s。
1.匹配成功的数字会从顺序排列in中被直接弹出,否则会压入栈buffer。
2.每当排列in顶端元素匹配成功后,都要返回buffer查看是否存在与栈refer的下一个元素匹配的元素,若存在则基础此操作;若不存在,则返回操作1。
实现代码如下:
public class Exist {
static Stack<Integer> in = new Stack<Integer>(); //0 1 2 3...
static Stack<Integer> refer = new Stack<Integer>(); //乱序
static Stack<Integer> buffer = new Stack<Integer>();
static int printNum = 0;
static String s = "";
public static boolean bufferPop() {
if(!buffer.isEmpty()) {
if(buffer.top() == refer.top()) {
printNum ++;
buffer.pop();
refer.pop();
s = s + "-";
bufferPop();
return true;
}
}
return false;
}
public static void bufferPush() {
while(!in.isEmpty()) {
int inNum = in.pop();
int referNum = refer.top();
s = s + inNum;
if(inNum == referNum) {
printNum ++;
refer.pop();
s = s + "-";
bufferPop();
} else {
buffer.push(inNum);
}
}
while(!refer.isEmpty() && bufferPop()) {
bufferPop();
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
for(int i = 9; i >= 0; i --) {
refer.push(Integer.parseInt(args[i]));
in.push(i);
}
bufferPush();
if(printNum == 10) {
System.out.println(s);
}
}
}
bufferPop()函数和bufferPush函数存在相似的代码段,考虑是否能将此代码进行简化,删除杂糅的部分。
思路b:设给定的乱序排列为(参考)栈refer,顺序排列为(输入)栈in,为即使出栈的整数被存储在栈buffer。成功出栈次数为printNum,打印结果为s,上一次是否弹出成功标志位success。
1.根据书中的提示,栈in中的元素先考虑入栈到buffer。若buffer为空或buffer中上一次弹出不成功,则需要进行入栈。
2.buffer的顶端元素和栈refer顶端元素进行匹配,若匹配成功则从buffer中弹出此元素。重复这两步操作
实现代码如下:
public class MixUp {
static Stack<Integer> in = new Stack<Integer>(); //0 1 2 3...
static Stack<Integer> refer = new Stack<Integer>(); //乱序
static Stack<Integer> buffer = new Stack<Integer>(); //未弹出缓存
static int printNum = 0; //“-”打印次数
static String s = ""; //输出
static boolean success = false; //上一次是否弹出成功
public static void bufferInOut() {
while(!refer.isEmpty()) {
if(!success || buffer.isEmpty()) { //未成功弹出或buffer已空都要再次入栈
buffer.push(in.pop());
s = s + buffer.top();
}
int inNum = buffer.top();
int referNum = refer.top();
if(inNum == referNum) {
printNum ++;
refer.pop();
s = s + "-";
buffer.pop();
success = true;
} else
success = false;
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
for(int i = 9; i >= 0; i --) {
refer.push(Integer.parseInt(args[i]));
in.push(i);
}
bufferInOut();
if(printNum == 10) {
System.out.println(s);
}
}
}
问题:题目要求“你使用的空间量与N无关,即不能用某种数据结构存储所有整数”,不清楚这里的“所有整数”的指代什么,且设计的算法使用空间量与N有关。但是这个算法是一个线性时间的算法。