给定一个正整数N代表火车数量,0
数据范围: 1 ≤ n ≤ 10 1\le n\le 10 1≤n≤10
进阶:时间复杂度: O ( n ! ) O(n!) O(n!),空间复杂度: O ( n ) O(n) O(n)
第一行输入一个正整数N(0 < N <= 10),第二行包括N个正整数,范围为1到10。
输出以字典序从小到大排序的火车出站序列号,每个编号以空格隔开,每个输出序列换行,具体见sample。
输入:
3
1 2 3
输出:
1 2 3
1 3 2
2 1 3
2 3 1
3 2 1
说明:
第一种方案:1进、1出、2进、2出、3进、3出
第二种方案:1进、1出、2进、3进、3出、2出
第三种方案:1进、2进、2出、1出、3进、3出
第四种方案:1进、2进、2出、3进、3出、1出
第五种方案:1进、2进、3进、3出、2出、1出
请注意,[3,1,2]这个序列是不可能实现的。
用 used 数组标记使用情况,回溯,对数组进行全排列,同时检查排列组合是否符合出栈序列,记录符合的结果,然后用 sort 进行排序。
#include
#include
#include
#include
using namespace std;
vector<vector<int>> ans;
vector<int> path;
bool check(vector<int>& list, vector<int>& path){ // 验证出栈序列
stack<int> st;
int idx = 0;
for(int num : list){
st.push(num);
while(!st.empty() && st.top() == path[idx]){
st.pop();
++idx;
}
}
return st.empty();
}
void backtrack(vector<int>& list, vector<bool>& used){
if(path.size() == list.size()){
if(check(list, path)) ans.emplace_back(path);
return;
}
for(int i = 0; i < list.size(); ++i){ // used数组标记、进行全排列
if(used[i] == 0){
path.emplace_back(list[i]);
used[i] = 1;
backtrack(list, used);
used[i] = 0;
path.pop_back();
}
}
}
int main(){
int n;
while(cin >> n){
vector<int> list(n, 0);
for(int i = 0; i < n; ++i){
cin >> list[i];
}
vector<bool> used(n, 0);
backtrack(list, used);
sort(ans.begin(), ans.end());
for(auto nums : ans){
for(int num : nums){
cout << num << " ";
}
cout << endl;
}
}
}
每次 dfs 递归,存在两种操作:
1、从 list 数组中取一个数压入栈中;
2、取出栈顶元素。
因此,我们用回溯得到出栈序列的全排列,最后进行排序。
#include
#include
#include
#include
using namespace std;
vector<vector<int>> ans;
vector<int> path;
void backtrack(vector<int>& list, int idx, stack<int>& st){
if(path.size() == list.size()){ // 排列完成
ans.emplace_back(path);
return;
}
for(int i = 1; i <= 2; ++i){ // 递归的两种选择
if(i == 1){ // 入栈
if(idx < list.size()){
st.push(list[idx]); // 入栈
backtrack(list, idx+1, st); // list元素入栈,递归、指针右移
st.pop(); // 回溯
}
}else{ // 出栈
if(!st.empty()){
int temp = st.top();
path.emplace_back(temp); // 出栈
st.pop();
backtrack(list, idx, st); // 未操作list数组,递归、指针不变
st.push(temp); // 回溯
path.pop_back();
}
}
}
}
int main(){
int n;
while(cin >> n){
vector<int> list(n, 0);
for(int i = 0; i < n; ++i){
cin >> list[i];
}
stack<int> st;
backtrack(list, 0, st);
sort(ans.begin(), ans.end()); // 排序
for(auto nums : ans){
for(int num : nums){
cout << num << " ";
}
cout << endl;
}
}
}