题目描述
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
输入描述:
输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。
参考思路
这题是典型的排列组合问题,一般都可以采用递归回溯来解决。其中需要注意的是结果集需要按照升序排序,因此我们选用TreeSet而不是使用HashSet,虽然两者都可以去重。此外还需要一个用来存储访问状态的数组visited[]数组。
回溯条件:
得到一个排列结果则返回。
状态重置:
排列长度-1;当前排列结果去掉最后一个字符。
参考代码
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.TreeSet;
public class Solution {
private ArrayList<String> res = new ArrayList<>();
//用于所有路径的去重
private TreeSet<String> paths = new TreeSet<>();
//用于记录每一条路径,StringBuilder可以用来实现动态增删
private StringBuilder path = new StringBuilder();
private int[] visited;
public ArrayList<String> Permutation(String str) {
if(str == null || str.equals("")) {
return res;
}
visited = new int[str.length()];
char[] charArr = new char[str.length()];
charArr = str.toCharArray();
//用于对字符数组排序
Arrays.sort(charArr);
combination(charArr, 0);
res.addAll(paths);
return res;
}
public void combination(char[] charArr,int length) {
if(length == charArr.length) {
paths.add(path.toString());
return;
}
for (int i = 0; i < charArr.length; i++) {
if (visited[i] == 0) {
visited[i] = 1;
path.append(charArr[i]);
combination(charArr, length+1);
//下面表示回溯代码,包括状态重置
visited[i] = 0;
path.deleteCharAt(path.length()-1);
}
}
}
}