参考自:《剑指Offer——名企面试官精讲典型编程题》
题目:字符串的排列
输入一个字符串,打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a、b、c所能排列出来的所有字符串abc、acb、bac、bca、cab和cba。
主要思路:把字符串看成两部分,第一部分是它的第一个字符,第二部分是后面的字符。第一步,求所有可能出现在第一个位置的字符,即把首字符逐个与后面的字符交换,得到首字符的所有排列情况。第二步,求首字符后面字符串的排列,可通过递归实现。
关键点:递归,排列组合一般可通过递归实现
时间复杂度:O(n)
public class StringPermutation
{
public static void main(String[] args)
{
String str = "abc";
Set<String> result = permutation(str);
System.out.println(result);
}
private static Set<String> permutation(String str)
{
if (str == null || str.equals("")) return new TreeSet<>();
char[] chars = str.toCharArray();
//有序非重复的排列结果
Set<String> result = new TreeSet<>();
permutate(chars, 0, result);
return result;
}
private static void permutate(char[] chars, int begin, Set<String> result)
{
//递归到字符串尾部
if (begin == chars.length - 1)
{
String str = String.valueOf(chars);
result.add(str);
} else
{
//首部字符与后面的字符逐个交换
for (int i = begin; i < chars.length; i++)
{
swap(chars, begin, i); //交换
//递归求后面字符串的排列
permutate(chars, begin + 1, result);
swap(chars, begin, i); //归位
}
}
}
private static void swap(char[] chars, int a, int b)
{
if (a == b) return;
char temp = chars[a];
chars[a] = chars[b];
chars[b] = temp;
}
}