dfs
牛客华为机试 HJ77 火车进站
下面是我写的一种方法,输出字符串序列,再排序
或者也可以先全排列,再针对每个排列结果进行检验是否是合法的出栈序列。
检验合法出栈序列可以参考leetcode946题
#include <iostream>
#include <stack>
#include <vector>
#include <algorithm>
using namespace std;
vector<int> arr;
vector<string> ans;
string res;
stack<int> stk;
int idx, n;//当前未入栈的最小索引
void dfs() {
//如果全部出栈完了,输出
if (res.size() == 2 * n) {
res.pop_back();//去除最后一个空格
ans.push_back(res);
res.push_back(' ');//补上,不然回溯pop两次出问题
return;
}
//如果给定的进栈序列是有序的话,字典序从小到大,栈顶元素一定要小于未入栈的,所以出栈结果是字典序小的
//每层两种选择,1.出栈 2.入栈
if (stk.size()) {
int x = stk.top();
stk.pop();
res.push_back(x + '0');
res.push_back(' ');
dfs();
stk.push(x);
res.pop_back();
res.pop_back();
}
//入栈选择
if (idx < n) {
stk.push(arr[idx ++]);
dfs();
stk.pop();
idx --;
}
}
int main() {
cin >> n;
arr = vector<int>(n);
for (int i = 0; i < n; i ++)
cin >> arr[i];
dfs();
sort(ans.begin(), ans.end());
for (auto& r: ans) cout << r << endl;
return 0;
}
129. 火车进栈 acwing 对上面稍加修改即可,这个简单多了,给定序列是有序的
#include <iostream>
#include <stack>
#include <vector>
#include <algorithm>
using namespace std;
vector<int> arr, res;
stack<int> stk;
int idx, n;//当前未入栈的最小索引
int cnt = 20;
void dfs()
{
if(cnt)
{
//如果全部出栈完了,输出
if(res.size() == n){
for(auto a: res) cout << a;
puts("");
cnt --;
return;
}
//字典序从小到大,栈顶元素一定要小于未入栈的,所以出栈结果是字典序小的
//每层两种选择,1.出栈 2.入栈
if(stk.size()){
int x = stk.top(); stk.pop();
res.push_back(x);
dfs();
stk.push(x);
res.pop_back();
}
//入栈选择
if(idx < n){
stk.push(arr[idx ++]);
dfs();
stk.pop();
idx --;
}
}
}
int main() {
cin >> n;
arr = vector<int>(n);
for(int i = 0; i < n; i ++)
arr[i] = i + 1;
dfs();
return 0;
}