题目描述
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
思路
大脑短路了,想明白这个竟然花了半小时。这个题目的核心其实是求解一个字符串的全排列。因为字典序只需要用
Collection.sort()方法排序一个ArrayList 或者TreeSet就行了。
主要说下怎么对一个字符串进行全排列。比如说”abcd”怎么全排序呢?直觉告诉我们先把a放第一位,对”bcd”再进行全排列,就是一个递归。然后把b放在第一位,”acd”进行递归。…具体操作下面结合代码说。
下面就是对全排列的字符串进行排序操作,按字典序输出即可。
代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| import java.util.ArrayList; import java.util.Collections;
public class StringPermutationSort {
public ArrayList<String> Permutation(String str) { ArrayList<String> result = new ArrayList<>(); if (str != null && str.length() > 0) { Permutation(str.toCharArray(), 0, result); } Collections.sort(result); return result; }
private void Permutation(char[] charArray, int i, ArrayList<String> result) { if (i == charArray.length - 1) { result.add(String.valueOf(charArray)); } else { for (int j = i; j <= charArray.length - 1; j++) { if (j != i && charArray[j] == charArray[i]) continue; swap(charArray, i, j); Permutation(charArray, i + 1, result); swap(charArray, i, j); } } }
private void swap(char[] s, int i, int j) { if (s[i] == s[j]) { ; } else { char c = s[i]; s[i] = s[j]; s[j] = c; } } }
|
回头再看究竟是怎么全排列的吧。就是这个函数 private void Permutation(char[] charArray, int i, ArrayList result) 的递归过程。其中 i 表示起始位置,从i这个位置开始向后寻找下面字符的全排列。当i == charArray.length - 1 时,表示已经到了最后一个字符,那么就找到了一个全排列。下面很好看懂,就是递归向下找,但是为什么要交换两次 charArray i和j 位置的字符呢?
其实拿”abcd”来说,当我们交换 a和b 的位置(第一次交换),然后用b作为首字符寻找全排列。但是下次我们要交换 a和c 的位置,但是这时候 a和b 已经交换了,所以要把 a和b 换回来,才能保证每次交换的顺序没有乱。