题目描述
输入一个入栈序列,输出可能的出栈序列。
输入格式
第一行输入一个整数 N ,表示入栈序列的长度。
第二行输入 n 个数字,表示入栈序列。
输出格式
输出所有可能的出栈序列
输入样例
3
1 2 3
输出样例
1 2 3
1 3 2
2 1 3
2 3 1
3 2 1
解题思路
很容易看出来,本题目是一道递归题。可以通过穷举遍历得到结果,因为对于任意一个栈状态,我们有两种选择,一种是向栈中添加元素,另外一种是从栈中取出元素。
首先是需要哪些变量存储信息。
需要一个变量 N 存储入栈序列个数。
需要一个数组 data 存储入栈序列。
需要一个变量 index 存储当前需要入栈的元素下标。
需要一个栈 input 模拟入栈出栈操作。
需要一个栈 output 存储出栈结果。
使用局部变量(状态通过函数参数体现)解决比较简单。
这里我使用全局变量进行解决,重点在于进行递归完后,需要恢复状态。
在递归函数中,如果index == N表明,入栈操作已经全部完成,此时对应的出栈结果已经确定,将 input 中的元素依次放入 output 中,然后从栈底依次输出元素,即为出栈结果。
如果 index != N,表明还有元素需要入栈,那么此时操作有两种,一种是先出栈一个元素,或者先入栈一个元素,然后依次递归下去。
stack<int> input,output;
int N;
void dfs(int index,int* data)
{
if(index == N)
{
// 从全局中获取这两个栈
stack<int> outtmp(output);
stack<int> intmp(input);
// 将input栈清空到output栈中
while(intmp.size())
{
int num = intmp.top();
intmp.pop();
outtmp.push(num);
}
// 为实现输出结果,需要先将output栈中元素输入到一个栈中,然后从该栈中输出,这样可以实现从栈底到栈顶的遍历
// 为减少空间代价,这里选择的这个栈为input
while(outtmp.size())
{
intmp.push(outtmp.top());
outtmp.pop();
}
while(intmp.size())
{
cout << intmp.top() << " ";
intmp.pop();
}
cout << endl;
return ;
}
// 栈不为空,先选择出栈
if(input.size())
{
int num = input.top();
input.pop();
output.push(num);
dfs(index,data);
output.pop();
input.push(num);
}
//然后选择入栈
input.push(data[index]);
dfs(index + 1,data);
input.pop();
}