Medium | 剑指 Offer 38. 字符串的排列 | 回溯
剑指 Offer 38. 字符串的排列
输入一个字符串,打印出该字符串中字符的所有排列。
你可以以任意顺序返回这个字符串数组,但里面不能有重复元素。
示例:
输入:s = "abc"
输出:["abc","acb","bac","bca","cab","cba"]
限制:
1 <= s 的长度 <= 8
解题思路: 回溯算法 + 排列问题
- 如何获得所有的排列:
首先尝试着把所有元素放到第一位, 可以通过交换的方式, 然后递归后面的字符串。并且由于输入字符串有重复元素, 而输出不允许有重复, 可以在每个递归的方法内 , 设置一个set, 来保存所有已经放到当前位置的所有字符。
private List<String> res = new ArrayList<>();
public String[] permutation(String s) {
char[] c = s.toCharArray();
permutation(c, 0);
return res.toArray(new String[0]);
}
public void permutation(char[] c, int index) {
// 递归出口
if (index == c.length) {
res.add(String.valueOf(c));
return;
}
Set<Character> set = new HashSet<>();
// 把后面的所有元素依次放到当前index位置上
for(int i = index; i < c.length; i++) {
if (set.contains(c[i])) { // c[i]这个数字曾经放到index位置过, 进行剪枝
continue;
}
set.add(c[i]); // 记录放到index位置的每个元素
swap(c, index, i);
// 递归后面的元素
permutation(c, index+1);
// 将交换过的元素还原回来
swap(c, index, i);
}
}
public void swap(char[] arr, int idx1, int idx2) {
if (idx1 == idx2) return;
char temp = arr[idx1];
arr[idx1] = arr[idx2];
arr[idx2] = temp;
}