全排列演算法(java實現)
100題目之53題目和70題目
在做100題目的時候,全排列的演算法困擾了很久,雖然網上了搜了一些資料,可是並沒有搞懂。今天花了一個下午的時間,從新梳理了一遍,終於弄明白了。
全排列的演算法,遞迴分析網上都有:
設一組數p = {r1, r2, r3, ... ,rn}, 全排列為perm(p),pn = p - {rn}。
因此perm(p) = r1perm(p1), r2perm(p2), r3perm(p3), ... , rnperm(pn)。當n = 1時perm(p} = r1。
實現java程式碼如下:
- publicclass permutate {
-
public
- publicstaticvoid swap(String[] str, int i, int j)
- {
- String temp = new String();
- temp = str[i];
- str[i] = str[j];
- str[j] = temp;
- }
- publicstaticvoid 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);
- }
- }
- }
- /**
- * @param args
- */
- publicstaticvoid main(String[] args) {
- // TODO Auto-generated method stub
- 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"。
類似的,就可以輸出所有的排列了。