1.题目描述
输入一个字符串,打印出该字符串中字符的所有排列。
你可以以任意顺序返回这个字符串数组,但里面不能有重复元素。
示例1:
输入:s = "abc" 输出:["abc","acb","bac","bca","cab","cba"]
2.思路
这道题和数值的全排列问题基本一致,唯一的不同是这道题要求不能包含重复的字符串。除此之外用LinkedList记录路径时,不能直接进行剪枝,因此需要用额外的数组进行记录。
3.解答
class Solution {
//回溯算法
//返回结果
ArrayList<String> res = new ArrayList<>();
public String[] permutation(String s) {
//记录路径
StringBuilder track = new StringBuilder();
//记录已经访问过的路径
boolean[] visited = new boolean[s.length()];
char[] arr = s.toCharArray();
Arrays.sort(arr);
backTrack(arr, track, visited);
return res.toArray(new String[0]);
}
//辅助方法:回溯
public void backTrack(char[] arr, StringBuilder track, boolean[] visited){
//触发结束条件
if(track.length() == arr.length){
res.add(track.toString());
return;
}
//遍历每一个字符
for(int i = 0; i < arr.length; i++){
//同一个字符如果已经访问过了则直接跳过
if(visited[i] || (i > 0 && !visited[i - 1] && arr[i] == arr[i - 1])){
continue;
}
//做选择
track.append(arr[i]);
visited[i] = true;
//递归
backTrack(arr, track, visited);
//撤销选择
track.deleteCharAt(track.length() - 1);
visited[i] = false;
}
}
}