输入一个字符串,打印出该字符串中字符的所有排列。
你可以以任意顺序返回这个字符串数组,但里面不能有重复元素。
示例:
输入:s = “abc”
输出:[“abc”,“acb”,“bac”,“bca”,“cab”,“cba”]
限制:
1 <= s 的长度 <= 8
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/zi-fu-chuan-de-pai-lie-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
字符串排列,此题我们使用深搜加剪枝以及回溯来解决,思路如下:
拿 abc 来举例,分为三步,分别是 a 打头,b 打头和 c 打头,如图:
从第 0 号位置开始深度优先搜索,如果位置 x 等于 c 的最后一位,直接加入 list 中,如果不等于就开始循环再深搜,需要注意的是,每一层对应一个 HashSet, 为了防止有重复字母出现的情况,比如 abb,bbc 等,每次深搜加入 list 以后,交换位置,然后继续。
class Solution {
char[] c;
LinkedList<String> list = new LinkedList<>();
public String[] permutation(String s) {
c = s.toCharArray();
Dfs(0);
String[] ss = list.toArray(new String[list.size()]);
return ss;
}
public void Dfs(int x) {
if (x == c.length - 1) {
list.add(String.valueOf(c));
return;
}
HashSet<Character> set = new HashSet<>();
for (int i = x; i < c.length; i++) {
if (set.contains(c[i]) ) continue;//如果存在,说明有重复元素,继续循环
set.add(c[i]);
swap(i, x);// 交换位置
Dfs(x + 1);
swap(i, x);//把位置换回来
}
}
public void swap(int x, int y) {
char temp = c[x];
c[x] = c[y];
c[y] = temp;
}
}