算法复杂度:n!;//记录自己的进步——
具体思路:
- 用两个数组:一个数组存排好的排列,另外一个数组记录是否用过了这个值
-
核心代码
for(int i=1;i<=n;i++){ if(book[i]==0){//没有用到这个值 a[step]=i;//将这个值传到a数组里面 book[i]=1;//标记一下这个值已经用到了; dfs(step+1);//继续寻找下一个值(同样从将数组book从1遍历到n寻找值为0的值) book[i]=0;//回溯 } }
- 限定条件出口
if(step==n+1){ for(int i=1;i<=n;i++) cout<<a[i]<<" "; cout<<endl; return; }
- 对于我来说的最大理解难处就是没有理解到递归的过程
- 就把这个dfs路径想成一颗树
- 但是这颗树可不是立刻就能得到的
- 需要遍历好多次,但是每次遍历,只能遍历一个分支。
- 如果许多分支和上一个分支有共同的父节点,那就再回溯到父节点的上个点,继续向下排列新的数进行组合
- 可以画个二叉树,到底遍历完一个分支,再由底部向上回溯,回溯到一定程度,再向下遍历到底
代码:
#include<bits/stdc++.h>
using namespace std;
int a[100],book[100],n;
void dfs(int step){
if(step==n+1){
for(int i=1;i<=n;i++)
cout<<a[i]<<" ";
cout<<endl;
return;
}
for(int i=1;i<=n;i++){
if(book[i]==0){
a[step]=i;
book[i]=1;
dfs(step+1);
book[i]=0;
}
}
return;
}
int main(){
cin>>n;
dfs(1);
return 0;
}