----------------------------------------------本题链接----------------------------------------------
题目描述
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则按字典序打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。
示例
输入
"ab"
返回值
["ab","ba"]
思路
全排列问题
采用回溯算法,解决一个回溯问题,实际上就是一个决策树的遍历过程
回溯算法3个要点:
- 路径:也就是已经做出的选择。
- 选择列表:也就是你当前可以做的选择。
- 结束条件:也就是到达决策树底层,无法再做选择的条件。
推荐大佬总结的回溯算法问题:labuladong的算法小抄
算法过程
回溯算法框架如下:
private List<> res;
private void backtrack(选择列表,路径){
if(满足终止条件){
res.add(路径);
return;
}
for(选择 : 选择列表){
做选择
backtrack(选择列表,路径);
撤销上一步选择
}
}
解答
public class Solution {
ArrayList<String> res = new ArrayList<>();
public ArrayList<String> Permutation(String str) {
if(str.length() == 0 || str == null) return res;
char[] ch = str.toCharArray();
backtrack(ch, 0);
Collections.sort(res);
return res;
}
private void backtrack(char[] ch, int pos){
if(pos == ch.length){
res.add(String.valueOf(ch));
return;
}
Set<Character> set = new HashSet<>();
for(int i = pos; i < ch.length; i++){
if(pos != i && set.contains(ch[i])) continue;
set.add(ch[i]);
swap(ch, i, pos);
backtrack(ch, pos+1);
swap(ch, pos, i);
}
}
private void swap(char[] ch, int i, int j){
char tmp = ch[i];
ch[i] = ch[j];
ch[j] = tmp;
}
}