原题地址:https://leetcode-cn.com/problems/zi-fu-chuan-de-pai-lie-lcof/
题目描述:
解题方案:
开始用的普通回溯,set去重,而且用的是StringBuilder,但是复杂度比较高。优化是改用了交换法回溯,节省空间,并且用char数组操作也更快,去重改用了标记数组,比set更快,但这道题是只有小写字母,如果还有其他字符的话标记数组就不能使用了。
代码:
交换法:
class Solution {
List<String> res;
char[] ans;
public String[] permutation(String s) {
res = new ArrayList<>();
ans = s.toCharArray();
DFS(s, 0, 0, ans);
return res.toArray(new String[res.size()]);
}
void DFS(String s, int size, int start, char[] ans)
{
int len = s.length() - 1;
if(start == len)
{
res.add(new String(ans));
return;
}
boolean[] visited = new boolean[26];
for(int i = start; i <= len; i ++)
{
if(visited[ans[i] - 'a'] == false)
{
visited[ans[i] - 'a'] = true;
swap(start, i);
DFS(s, size + 1, start + 1, ans);
swap(i, start);
}
}
}
void swap(int a, int b)
{
char tmp = ans[a];
ans[a] = ans[b];
ans[b] = tmp;
}
}
普通回溯:
class Solution {
Set<String> res;
StringBuilder ans;
public String[] permutation(String s) {
res = new HashSet<>();
// if(s.length() == 0) return new String[""];
ans = new StringBuilder(s);
DFS(s, 0, 0, ans);
return res.toArray(new String[res.size()]);
}
void DFS(String s, int size, int start, StringBuilder ans)
{
int len = s.length() - 1;
if(start == len)
{
res.add(new StringBuilder(ans).toString());
return;
}
for(int i = start; i <= len; i ++)
{
swap(start, i);
DFS(s, size + 1, start + 1, ans);
swap(i, start);
}
}
void swap(int a, int b)
{
char tmp = ans.charAt(a);
ans.setCharAt(a, ans.charAt(b));
ans.setCharAt(b, tmp);
}
}