Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
一、题目描述:
给定一个整数 n,将数字 1∼n
排成一排,将会有很多种排列方法。
现在,请你按照字典序将所有的排列方法输出。
输入格式
共一行,包含一个整数 n。
输出格式
按字典序输出所有排列方案,每个方案占一行。
数据范围
1≤n≤7
输入样例:
3输出样例:
1 2 3 1 3 2 2 1 3 2 3 1 3 1 2 3 2 1
二、思路分析:
-
这一题从题目上看是一个全排列的问题,我们可以利用DFS来解决这个问题
具体解题思想为:
例如:n = 3
- 预留n个空位用以填数字。 _ _ _
- 先列出第一个位置的所有可能。1 _ _ 和 2 _ _ 和 3 _ _
- 在以第一种情况的前提下去列出第二个位置的所有可能。1 2 _ 和 1 3 _
- 同样再填第3个位置。
- 直到位置填完输出排列后的情况,回溯。
如图:
-
这一题的容易错误的地方:
for (int j = 1; j <= N; j++) { if(!visted[j]){ dfs(i,j); visted[j] = false; } }完整的输出一个数组后,回溯时要把数字设置为未访问状态。可以看做把位置再空出来。
三、AC 代码:
import java.util.Scanner;
public class PaiLieSZ {
public static int N = 0;
public static int [] num = null;
public static boolean[] visted = null;
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
N = scan.nextInt();
num = new int[N];
visted = new boolean[N + 1];
for (int j = 1; j <= N; j++) {
dfs(0, j);
visted = new boolean[N + 1];
}
scan.close();
}
public static void dfs(int i,int x){
if( i == num.length -1 ){
num[i] = x;
for (int j = 0; j < num.length; j++) {
System.out.print(num[j]);
}
System.out.println("");
return;
}
if(visted[x]){
return;
}
num[i] = x;
visted[x] = true;
i++;
for (int j = 1; j <= N; j++) {
if(!visted[j]){
dfs(i,j);
visted[j] = false;
}
}
}
}
四、总结:
要灵活转化思维,把全排列问题转化为DFS问题去解决、