引言
麻蛋,这玩意碰到好几次了,一直没能掌握要领,还有就是递归,对于我这种非科班的人简直是太残忍了,话不多说,今晚上一定要get到!
概念
从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一个排列。当m=n时所有的排列情况叫全排列。
公式:全排列数f(n)=n!(定义0!=1)。
eg:输入为{‘a’,’b’,’c’},则其全排列组合为abc,acb,bac,bca,cba,cab。
递归算法
递归算法有四个特性:
必须有可达到的终止条件,否则程序陷入死循环
子问题在规模上比原问题小
子问题可通过再次递归调用求解
子问题的解应能组合成整个问题的解
对于上述的那个例子,首先,将a固定为第一个字符,求后边两个字符bc的排列,当两个字符bc排列求好以后,我们把第一个字符a和后边的字符b交换,得到bac,接着固定b,求ac的排练。最后是把c进行固定。
java代码
/** * 全排列算法 */
public class Permutate {
public static int total = 0;
public static void swap(String []str,int i,int j) {
String temp = new String();
temp = str[i];
str[i] = str[j];
str[j] = temp;
}
public static void arrange(String []str,int st,int len) {
if(st == len - 1) {
for (int i = 0;i < len;i ++) {
System.out.print(str[i] + " ");
}
System.out.println();
total ++;
}else {
for (int i = st;i < len;i++) {
swap(str,st,i);
arrange(str,st+1,len);
swap(str,st,i);
}
}
}
public static void main(String[] args) {
String str[] = {"a","b","c"};
arrange(str,0,str.length);
System.out.println(total);
}
}
自我理解
关键的就是arrange方法的else里面的内容,我的理解是(以求str[] = {“a”,”b”,”c”}的排列为例子):
用i从str[st]做一遍循环:
每一次循环中,都要将str[i]与str[i]互相调换位置:第一次开始,”a”与自己换,这时候,递归调用arrange[str,st + 1, len]
这是在求取str[str…len – 1]的排列即”b”,”c”的排列;
第二次,”a”与”b”互相调换,递归调用arrange[str,str + 1, len]就是在求取{“a”,”c”}的排列。
第三次,”a”与”c”互相调换,递归调用arrange[str, str + 1,len]就是在求取”{“b”,”a}的排列。
下面再以”b”,”c”的排列求取为例:
首先还是做循环,第一次,”b”与自己调换,这时候,调用arrange[str,st + 1,len], 就是求c的排列。呵呵,这时候终于到了函数递归调用的出口了: st = len – 1。输出”b” “c”;
第二次,类似的,输出”c”,”b”;
至此,”b” “c”的排列求取完毕。加上前面的a,就输出”a”“b”“c” “a”“c”“b”。
类似的,就可以输出所有的排列了。
[自我理解部分摘自]http://blog.csdn.net/randyjiawenjie/article/details/6313729