題目:終端隨機輸入一串字符串,輸出該字符串的所有排列。
例如,輸入:“abc”,輸出:abc、acb、bac、bca、cab、cba
【解決思想與辦法】
正常人的思維是,固定第一個字符,然后依次將后面的字符串與前面的交換,那么排列的個數就是除了第一個字符以外,其他字符的排列個數+1。也就是固定一個字符之后,再將問題變小,只需要求出后面子串的排列個數就可以得出結果,當然第一時間想到的就是遞歸的算法了。下面這張圖很清楚的給出了遞歸的過程:

很明顯,遞歸的出口,就是只剩一個字符的時候,遞歸的循環過程,就是從每個子串的第二個字符開始依次與第一個字符交換,然后繼續處理子串。還有一點就是可能會有重復數據,有人可能會采取向下比較策略即在交換之前做一次比較查看這兩個值是否一樣,我覺得大可不必,大不了有重復的,存放這些結果的容器選用HashSet即可,這樣不僅降低了程序的復雜度也能提升一定的程序效率,何樂而不為呢!
【關鍵詞提示】
permutation [pɜːmjʊ'teɪʃ(ə)n] 排列,置換 recursion [rɪ'kɜːʃ(ə)n] 遞歸,循環
具體代碼參看如下:
1 import java.util.ArrayList; 2 import java.util.HashSet; 3 import java.util.Scanner; 4 5 public class RecursionPermutation { 6 public static ArrayList<String> result = new ArrayList<String>(); 7 public static HashSet<String> set = new HashSet<String>(); 8 /** 9 * 主函數入口 10 * @param args 11 */ 12 public static void main(String[] args) { 13 System.out.println("請隨意輸入一串字符串:"); 14 String inputString = new Scanner(System.in).next().toString(); 15 ArrayList<String> result = Permutation(inputString); 16 for (int i = 0; i < result.size(); i++) { 17 System.out.println(result.get(i)); 18 } 19 } 20 21 /** 22 * 遞歸函數主入口 23 * @param str 24 * @return 25 */ 26 public static ArrayList<String> Permutation(String str) { 27 if (str == null || str.length() == 0) 28 return result; 29 else 30 Permutation(str, 0, str.length() - 1); 31 result.addAll(set); 32 return result; 33 } 34 35 /** 36 * 遞歸條件函數 37 * @param str 38 * @param start 39 * @param end 40 */ 41 public static void Permutation(String str, int start, int end) { 42 char[] array = str.toCharArray(); 43 String r = null; 44 if (start == end) { 45 r = String.valueOf(array); 46 set.add(r); 47 } else { 48 for (int i = start; i <= end; i++) { 49 char tmp = array[start]; 50 array[start] = array[i]; 51 array[i] = tmp; 52 53 Permutation(String.valueOf(array), start + 1, array.length - 1); 54 55 tmp = array[start]; 56 array[start] = array[i]; 57 array[i] = tmp; 58 } 59 } 60 } 61
以上代碼都在本機測試驗證通過,絕對保證無誤!!!