打印字符串全排列
题目1
问题描述:
对于不含重复元素的字符串,本题要求输入一个字符串,输出该字符串的全排列。
示例1:
输入:abc
输出:abc
acb
bac
bca
cba
cab
题目思路:
本题要求字符串全排列的问题,采用递归栈的形式去求解。即通过控制每一个位置,然后看其他位的排列组合数有几种。如abc,先控制a,然后bc有两种全排列;再让b放到首位,然后控制b,ac有两种组合;最后是控制c,看ab的组合数。
题目难度:
代码实现:
public static void printAllPermutations1(String str) {
if (str == null || str.length() == 0) {
return;
}
char[] chars = str.toCharArray();
process(chars, 0);
}
public static void process(char[] chars, int i) {
if (i == chars.length) {
System.out.println(String.valueOf(chars));
}
for (int j = i; j < chars.length; j++) {
swap(chars, i, j); //当其他的位置都控制住之后,用来交换剩下两位的位置,并打印出可能性
process(chars, i + 1);
swap(chars, i, j); //交换到首位及其之后位,用来固定
}
}
public static void swap(char[] chs, int i, int j) {
char tmp = chs[i];
chs[i] = chs[j];
chs[j] = tmp;
}
题目2
题目描述:
对于包含重复元素的字符串,本题要求输入一个字符串,输出该字符串的全排列。
示例1:
输入:acc
输出:acc
cac
cca
题目思路:
本题是在题目一的基础上的进阶版,要求包含重复元素的问题,就需要将遍历到的每一个元素,放入set集合中,然后进行相应递归。
代码实现:
public static void printAllNotEqual(String str) {
if (str == null) {
return;
}
char[] chars = str.toCharArray();
process1(chars, 0);
}
private static void process1(char[] chars, int i) {
if (i == chars.length) {
System.out.println(String.valueOf(chars));
}
HashSet<Character> set = new HashSet<>(); //用set来查看是否有重复元素
for (int j = i; j < chars.length; j++) {
if (!set.contains(chars[j])) { //如果不包含重复元素,就进行接下来的排列操作,
// 如果包含了,说明直接这种排列的可能已经打印
set.add(chars[j]);
swap(chars, i, j);
process1(chars, i + 1);
swap(chars, i, j);
}
}
}
public static void swap(char[] chs, int i, int j) {
char tmp = chs[i];
chs[i] = chs[j];
chs[j] = tmp;
}