当前位置: 首页剑指offer刷题第七期问题详情 【回溯专题】剑指 Offer 38. 字符串的排列 本问题对应课程链接:剑指offer刷题第七期 要求: 1、请打卡你的解题代码,如果能简单说一下思路则简单说一下思路。 2、给出你代码所用的时间复杂度和空间复杂度
共以下 7 个回答
解题思路
– 把字符串转换成字符数组
– 把问题转换成排列组合,只是需要额外考虑下字符重复的问题
【题解1】错误的写法,没有考虑到goods=”aab”,字符重复了就不能用了,但是基本思路是没有问题的
【题解2】改进版,能够ac,借助用数组去标识是否已经访问过
【题解2】参考题解,借助char[] chars比如abc,其中a已经被使用了,那么只需要排列b和c的关系即可
思路:递归处理 使用HashSet 处理重复问题
dfs解法
优先深度搜索,通过交换字符串位置得到所有排列,通过set来判断是否重复。
时间复杂度O(N!∗N),空间复杂度O(N)。
class Solution { res = new HashSet();
boolean[] visited;
Set
public String[] goodsOrder(String goods) {
visited = new boolean[goods.length()];
dfs(goods, new StringBuilder());
return res.toArray(new String[0]);
}
}
时间:O(n)
空间:O(n)
class Solution { res = new LinkedList<>(); set = new HashSet<>();
List
char[] arr;
public String[] goodsOrder(String goods) {
arr = goods.toCharArray();
dfs(0);
return res.toArray(new String[res.size()]);
}
void dfs(int x) {
if(x arr.length – 1) {
res.add(String.valueOf(arr)); // 添加排列方案
return;
}
HashSet
for(int i = x; i < arr.length; i++) {
if(set.contains(arr[i])) continue; // 重复,因此剪枝
set.add(arr[i]);
swap(i, x); // 交换,将 arr[i] 固定在第 x 位
dfs(x + 1); // 开启固定第 x + 1 位字符
swap(i, x); // 恢复交换
}
}
void swap(int a, int b) {
char tmp = arr[a];
arr[a] = arr[b];
arr[b] = tmp;
}
}
注意点:刚开始没有加set类型的record判断重复,导致用例“aab”无法通过。