题目描述:
输入一个字符串,打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a、b、c所能排列出来的所有字符串abc、acb、bac、bca、cab和cba。
解题思路:
我们求整个字符串的排列,可以看成两步,首先求可能出现在第一个位置上的字符,即把第一个字符和后面所有的字符交换。第二步固定一个字符,求后面所有字符的全排列。这是一个递归的思想。
代码:
public class PermutationTest {
public static void permutation(char[] str){
if(str == null){
return;
}
permutation(str, 0);
}
private static void permutation(char[] str, int begin) {
if(begin == str.length){
System.out.println(str);
}
else{
for(int i = begin; i < str.length; i++){
char temp = str[begin];
str[begin] = str[i];
str[i] = temp;
permutation(str, begin + 1);
temp = str[begin];
str[begin] = str[i];
str[i] = temp;
}
}
}
public static void main(String[] args) {
char[] str = {'a', 'b', 'c'};
permutation(str);
}
}
扩展
求字符的所有组合,同样也可用使用递归的方法予以解决。求n个字符的长度为m的组合的时候,我们把n个字符串分成两部分:第一个字符串和其余的所有字符串,如果组合里包含第一个字符串,则下一步在剩余的字符串里选取m-1个字符,如果组合里不包含第一个字符,则下一步在剩余的字符里选取m个字符。
另一中方法,就是利用位运算,比如:
a b c a b
1 1 1 1 1 0
如果每一个位都对应二进制中的1,那么abc的组合也就是1~7中的所有情况
import java.util.ArrayList;
import java.util.List;
public class CombinationTest {
public static boolean testBit(int num, int position){
return ((num & (0x01<<position)) != 0 ? true : false);
}
public static void combination(char[] str){
if(str == null){
return ;
}
int n = str.length;
List<Character> result = new ArrayList<Character>();
for(int i = 1; i < Math.pow(2, n); i++){
result.clear();
for(int j = 0; j < n; j++){
if(testBit(i, j)){
result.add(str[j]);
}
}
System.out.println(result);
}
}
public static void main(String[] args) {
char[] str = new char[]{'a', 'b', 'c'};
combination(str);
}
}