全排列
- 求全排列:全排列指的是:n个元素中取n个元素(全部元素)的所有排列组合情况。
- 求组合:n个元素,取m个元素(m<=n)的所有组合情况
- 求子集:n个元素的所有子集(所有的组合情况)
全排列常用解决方法:回溯法和邻里交换法
回溯:一般解决搜索问题,全排列也是一种搜索问题。
- 回溯:就是类似枚举的搜索尝试过程。在搜索过程中寻找问题的解。当发现不满足求解的条件时返回,尝试别的路径。
全排列可以使用试探的办法列举所有的可能性。一个长度为n的序列,所有的排列组合:n!
- 从集合中选取一个元素(n种情况),并标记该元素已经被使用。
- 在第一步的基础上递归到下一层,从剩余的n-1个元素中,按照第一步的方法再找到一个元素,重复(1)
- 依次类推,所有的元素都被标记,将元素存起来,取对比求解的情况
例题:
1.
A,2,3,4,5,6,7,8,9 共9张纸牌排成一个正三角形(A按1计算)。要求每个边的和相等。
下图就是一种排法。A
9 6
4 8
3 7 5 2这样的排法可能会有很多。
如果考虑旋转、镜像后相同的算同一种,一共有多少种不同的排法呢?
public class Main {
static int num[] = new int [10];
static boolean bool[] = new boolean[10];
static int cnt = 0;
public static void main(String[] args) {
dfs(1);
System.out.println(cnt/6); //3种镜像、3种旋转
}
public static void dfs(int n){
if(n==10){
if(num[1]+num[2]+num[3]+num[4]==num[4]+num[5]+num[6]+num[7]&&
num[4]+num[5]+num[6]+num[7]==num[7]+num[8]+num[9]+num[1]){
cnt++;
}
}
for(int i = 1; i < 10; i++){
if(!bool[i]){
bool[i]=true;
num[n] = i;
dfs(n+1);
bool[i]=false;
}
}
}
}