输入一个字符串,打印这个字符串中字符的全排列。
1. 首选考虑字符不重复的情况
eg:
输入:abc
输出:abc acb bac bca cab cba
思路:
考虑把复杂的问题分解成小的问题。比如,把一个字符串看成由两部分组成:第一部分是它的第一个字符;第二部分是后面的所有字符。而我们求整个字符串的排列,可以看成两步。第一步求所有可能出现在第一个位置的字符,即把第一个字符和后面所有的字符交换(这里有点全排列的意思)。第二步是固定第一个字符,求后面所有字符的排列。这时候我们仍把后面的所有字符分成两个部分:后面字符的第一个字符,以及这个字符之后的所有字符。然后把第一个字符和它后面的所有字符交换。
代码实现如下:
public static void printAllPermutations1(String str) {
if (str == null || str.length() == 0) {
return;
}
char[] chs = str.toCharArray();
process1(chs, 0);
}
public static void process1(char[] chs, int i) {
if (i == chs.length) {
System.out.println(String.valueOf(chs));
}
for (int j = i; j < chs.length; j++) {
swap(chs, i, j);
process1(chs, i + 1);
swap(chs, i, j);
}
}
2. 接下来考虑字符重复的情况
eg:
输入:acc
输出:acc cac cca
包含重复元素的问题,只需要将遍历到的每一个元素,放入set集合中即可。
代码实现如下:
public static void printAllPermutations2(String str) {
char[] chs = str.toCharArray();
process2(chs, 0);
}
public static void process2(char[] chs, int i) {
if (i == chs.length) {
System.out.println(String.valueOf(chs));
}
HashSet<Character> set = new HashSet<>();
for (int j = i; j < chs.length; j++) {
if (!set.contains(chs[j])) {
set.add(chs[j]);
swap(chs, i, j);
process2(chs, i + 1);
swap(chs, i, j);
}
}
}
完整代码如下:
package com.gxu.dawnlab_algorithm8;
import java.util.HashSet;
/**
* 打印一个字符串的全部排列(暴力递归解法)
* @author junbin
*
* 2019年7月12日
*/
public class Print_All_Permutations {
public static void printAllPermutations1(String str) {
if (str == null || str.length() == 0) {
return;
}
char[] chs = str.toCharArray();
process1(chs, 0);
}
public static void process1(char[] chs, int i) {
if (i == chs.length) {
System.out.println(String.valueOf(chs));
}
for (int j = i; j < chs.length; j++) {
swap(chs, i, j);
process1(chs, i + 1);
swap(chs, i, j);
}
}
public static void printAllPermutations2(String str) {
char[] chs = str.toCharArray();
process2(chs, 0);
}
public static void process2(char[] chs, int i) {
if (i == chs.length) {
System.out.println(String.valueOf(chs));
}
HashSet<Character> set = new HashSet<>();
for (int j = i; j < chs.length; j++) {
if (!set.contains(chs[j])) {
set.add(chs[j]);
swap(chs, i, j);
process2(chs, i + 1);
swap(chs, i, j);
}
}
}
public static void swap(char[] chs, int i, int j) {
char tmp = chs[i];
chs[i] = chs[j];
chs[j] = tmp;
}
public static void main(String[] args) {
String test1 = "abc";
printAllPermutations1(test1);
System.out.println("======");
printAllPermutations2(test1);
System.out.println("======");
String test2 = "acc";
printAllPermutations1(test2);
System.out.println("======");
printAllPermutations2(test2);
System.out.println("======");
}
}