面試:字符串的全排列

1.題目html

  輸入一個字符串,打印出該字符串中字符的全排列。例如輸入字符串abc,則打印出[cab, abc, cba, bca, bac, acb]java

題目難度適中,能夠考察遞歸、非遞歸、是否有無重複字符的全排列等。算法

2.思路數組

  對於全排列,好比有3個字符abc,共有3!=6種排列.ide

首先分析出數學遞歸公式。
假設abcde是一個輸入參數,輸出的值則是一個全排列集合。能夠有:spa

1 f(abcde)=a+f(bcde)
2 f(bcde)=b+f(cde)
3 f(cde)=c+f(de)
4 f(de)={de,ed}

定義:code

  • f(abc) : abc的全排列
  • d+f(abc) : d插入到f(abc)全排列的全部字符串的任意位置

3.僞代碼實現htm

1 FullPermutation(A, p, r)
2 if r-p <=1
3     add(set, A[pr])
4     add(set, A[rp])
5  return set
6 return A[p] + FullPermutation(A, p+1, r)

全排序一個完整的字符數組A,最初的調用是FullPermutation(A, 0, length[A]-1)。blog

定義:排序

  • A : 帶全排列的字符數組
  • p, r : 待全排列的子數組下標
  • set : 存放全排列的集合
  • add : 爲set增長一個字符串

時間複雜度:O(n!)

4.Java代碼實現

僞代碼寫算法的好處:不用關心代碼的細節,便於理解和記憶。

 1 import java.util.HashSet;
 2 import java.util.Set;
 3 
 4 public class FullPermutation {
 5     public static void main(String[] args) {
 6         char[] A = "abcd".toCharArray();
 7         Set<String> set = fullPer(A, 0, A.length - 1);
 8         System.out.println("set:" + set + "\nSize:" + set.size());
 9     }
10 
11     /**
12      * @param A 待全排列的字符數組
13      * @param p 子數組左邊界
14      * @param r 子數組右邊界
15      * @return 全排列的集合
16      */
17     static Set<String> fullPer(char[] A, int p, int r) {
18         if (r - p <= 1) {
19             char[] cs = new char[2];
20             cs[0] = A[p];
21             cs[1] = A[r];
22             Set<String> set = new HashSet<String>();
23             set.add(new String(cs));
24             cs[0] = A[r];
25             cs[1] = A[p];
26             set.add(new String(cs));
27             return set;
28         }
29         return insertChar(A[p], fullPer(A, p + 1, r));
30     }
31 
32     /**
33      * 將字符 c 插入到集合setIn全部字符串的任意位置
34      * @param c char
35      * @param setIn Set<String>
36      * @return  Set<String>
37      */
38     private static Set<String> insertChar(char c, Set<String> setIn) {
39         Set<String> set = new HashSet<String>();
40         for (String s : setIn) {
41             char[] cs = s.toCharArray();
42             int len = cs.length + 1;
43             char[] result = new char[len];
44             for (int i = 0; i < len; i++) {
45                 result[i] = c;
46                 for (int j = 0, k = 0; k < len - 1; j++, k++) {
47                     if (j == i)
48                         j++;
49                     result[j] = cs[k];
50                 }
51                 set.add(new String(result));
52             }
53         }
54         return set;
55     }
56 }
View Code

5.更上一層樓

有一種算法能夠獲得排序字符串的下一個字典序,利用它,能夠獲得字符串的全排列。

求字典序的算法叫作康託集。

參考:如何找出字符串的字典序全排列的第N種

6.More(參考此博文的介紹)

這種類型的題目推廣開來就是:求一個元素組中,全部知足必定條件的排列。

對於這種問題,在沒有很好的剪枝的前提下,每每採用先求出全部排列,而後一一檢驗是否知足條件。

相似的題目還有八皇后問題,求全部八皇后的排放方式。

相關文章
相關標籤/搜索