题目描述
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
基本思路
按照排列组合的思想,所有的字符串的种类为
A
n
n
=
n
∗
n
−
1
∗
.
.
.
∗
2
∗
1
,
其
中
n
为
字
符
串
的
长
度
A^n_n = n*n-1*...*2*1, 其中n为字符串的长度
Ann=n∗n−1∗...∗2∗1,其中n为字符串的长度也就是说每一位的选择数为未选择字符的个数。
这样我们可以将字符串分为两个部分:第一部分为已经选择过的字符,第二部分为未选择的字符。设第一部分在前,问题就是求所有可能出现在第二部分的第一个位置的字符,即把所有后面的字符与第一位交换,然后逐渐扩大第一部分。
基本步骤如下:
- 每交换一次,就固定第一个字符,然后递归求后面的字符的全排列。
- 恢复交换,为下一次交换做准备。
- 递归结束的条件为没有第二部分了。
具体解答步骤如下:
public ArrayList<String> Permutation(String str) {
if (str == null || str.length() == 0) {
return new ArrayList<String>();
}
TreeSet<String> result = new TreeSet<>();
permutationInline(str.toCharArray(), 0, result);
return new ArrayList<String>(result);
}
private void permutationInline(char[] str, int start, TreeSet<String> result) {
if (start >= str.length) {
result.add(new String(str));
}
for (int i = start; i < str.length; i++) {
char tmp = str[i];
str[i] = str[start];
str[start] = tmp;
permutationInline(str, start+1, result);
tmp = str[i];
str[i] = str[start];
str[start] = tmp;
}
}