无重复字符串的排列组合。编写一种方法,计算某字符串的所有排列组合,字符串每个字符均不相同。
示例1:
输入:S = “qwe”
输出:[“qwe”, “qew”, “wqe”, “weq”, “ewq”, “eqw”]
示例2:
输入:S = “ab”
输出:[“ab”, “ba”]
提示:
字符都是英文字母。
字符串长度在[1, 9]之间。
题解
这是标准的回溯法,上次在网上看到一个模板觉得很好:
void backtrack(选择列表, 当前路径){
if (当前路径满足最终条件) { // 一般是遍历到树的结尾了
result.add(当前路径)
return
}
for (选择列表中的所有选择 choice) {
// 判断是否是满足的?
if( choice 不满足条件) continue
将当前路径加上 该选择 得到新路径
backtrack(选择列表, 新路径)
此时需要回溯,将新路径中加上的选择删掉
}
}
根据这个模板,可以得到下面的代码:
import java.util.Arrays;
class Solution {
public String[] permutation(String S) {
String[] ans = new String[72 * 42 * 120];
if(S == null || S.length() == 0){
return ans;
}
// 定义路径
Map<String, Integer> index = new HashMap<>();
index.put("key", 0);
StringBuffer sb = new StringBuffer();
backtrack(ans, sb, S, index);
return Arrays.copyOfRange(ans, 0, index.get("key"));
}
public static void backtrack(String[] ans, StringBuffer sb, String s, Map index){
// 如果选择满足条件
if(sb.length() == s.length()){
Integer count = (Integer)index.get("key");
ans[count] = sb.toString();
count ++;
index.put("key",count);
return;
}
for(int i = 0; i < s.length(); i++){
// 做选择
if(sb.length() != 0 && containsStr(sb.toString(), s.charAt(i)))
continue;
sb.append(s.charAt(i));
backtrack(ans, sb, s, index);
// 撤销选择
sb.deleteCharAt(sb.length() -1);
}
}
public static boolean containsStr(String str, char s){
for (int i = 0; i < str.length(); i++) {
if(str.charAt(i) == s){
return true;
}
}
return false;
}
}