求 n个元素的全排列。利用递归的方式实现。
题目分析
例如对 abc 进行全排列,则所有结果为:
abc acb bac bca cab cba
分析易知:分别把各个字母放在首字母位置,然后其他的所有字母进行全排列, 这就有了构造的相似性,也就可以使用递归的思想。
public class N个元素全排列 {
public static void main(String[] args) {
char[] c = "ABCDE".toCharArray();
f(c, 0);
}
/**
* 递归实现n个元素的全排列
*
* @param c
* 数组名
* @param k
* 当前的交换位置,与其后的元素交换
*/
private static void f(char[] c, int k) {
// 注意: 程序的出口由for循环控制
for (int i = k; i < c.length; i++) {
char temp = c[k];
c[k] = c[i];
c[i] = temp;
f(c, k + 1);// 递归调用
// 回溯
// 交换完之后一定要换回原始数据,否则后边的交换就会变乱
temp = c[k];
c[k] = c[i];
c[i] = temp;
}
// 输出
if (k == c.length) {// 换完一轮之后打印结果
for (char d : c) {
System.out.print(d + " ");
}
System.out.println();
}
}
}
总结
1 构造递归时,参数k是关键, 递归的关键是构造相似性(相似非相同),若没有这个参数k,那么递归长度不会变,就会变成死循环,所以要多一个参数。
2 在解决交换位置的题目时,交换之后一定要重新换回来,便于接下来的交换,否则会乱。这称之为 回溯 。类似的还有 八皇后问题、迷宫问题 。