用代码实现全排列

来源:互联网 发布:c语言中数据类型转换 编辑:程序博客网 时间:2024/05/13 13:53

缘由

今天主要是研究编程之美上的24点的题,结果无意中引出了这个问题,也是面试的经典问题。


排列是什么

排列表示把集合中元素的所有按照一定的顺序排列起来。那么从对于一个集合有多少种排列是在高中就学过了的。公式如下:

例如:{1, 2, 3}的全排列为:
123;132;213;231;312;321;
共6个,即3!=3*2*1=6。

代码实现

那么用代码如何实现呢?这就是主要的难点。我想了很久,以为可以让计算机模仿人的行为。大概人的行为就是如下图所示的吧:

首先取一个元素,例如取出了1,那么就还剩下{2, 3}。然后再从剩下的集合中取出一个元素,例如取出2,那么还剩下{3}。以此类推,把所有可能的情况取一遍,就是全排列了。

那如何用代码表示呢?看了代码一步一步解析:

public class Permutation {       public static void permutation(char[]ss,int i){           if(ss==null||i<0 ||i>ss.length){               return;           }           if(i==ss.length){               System.out.println(new String(ss));           }else{               for(int j=i;j<ss.length;j++){                   char temp=ss[j];                ss[j]=ss[i];                   ss[i]=temp;                   permutation(ss,i+1);                   temp=ss[j];                 ss[j]=ss[i];                   ss[i]=temp;               }           }       }       public static void main(String args[]){           char []ss={'a','b','c'};           permutation(ss,0);       }   }  
上面的代码,运行可以得到正确的结果。其中核心在于:
for(int j=i;j<ss.length;j++){                   char temp=ss[j];                ss[j]=ss[i];                   ss[i]=temp;                   permutation(ss,i+1);                   temp=ss[j];                 ss[j]=ss[i];                   ss[i]=temp;   }  
跟着思路来一遍,当第一次来到这个循环的时候,i=0。那么下面i和j的元素的互换其实没有实质的改变。
char temp=ss[j];ss[j]=ss[i];   ss[i]=temp;  
接着递归执行了
permutation(ss,i+1);这一步意思就是将这个问题化了子问题,那就是本来求abc的排列,现在求bc的排列,而i+1=1,就是固定了前面第一个字符,也就是a。在递归中的排列并不会影响到a,也就是已经确定的字符。

接着代码又将i和j的元素互换了一下。为什么呢?这就是难点所在。但是如果看下一个循环就非常清楚了,当j=2时,那么递归前的互换,将abc中的ab互换,变成了bac,此时,再执行递归,就固定了第一个元素b,而去求ac的排列。同样,当求完了ac的排列之后,permutation()函数返回时又会将bac变回abc,这其实是为了下一个循环做准备,这是因为当abc的下一个循环会让a与c互换,成了cba,再去求ba的全排列。

通过最简单的abc三个数字全排列的解释,应该很容易理解4、5、甚至更多的排列是如何成功运行的。

在整个过程中还有一个要点就是,前面的固定,也就是permutation(ss,i+1);的第二个参数,可以看到for循环内的j的第一个取值是根据i来决定的,所以i这个数的大小就将整个字符序列变为了两个部分。

  • 前一部分是这次求排列的过程中不动的部分
  • 从i开始的后一部分是这次求排行中会动的部分

参考博客

  1. 排列-组合的代码实现
  2. 排列与组合的Java递归实现


0 0