【回溯】经典的排列题目,解决这类题目的精髓就是通过回溯法,将当前t位置的字符和其他位置的字符进行交换。
class Solution {
Set<String> set = new HashSet();
char[] c;
int n;
public void swap(int i, int j){
char tmp = c[i];
c[i] = c[j];
c[j] = tmp;
}
public void backTrack(int t){
if(t == n) set.add(String.valueOf(c));
else{
for(var i = t; i < n; i++){
swap(i, t);
backTrack(t + 1);
swap(i, t);
}
}
}
public String[] permutation(String s) {
c = s.toCharArray();
n = c.length;
backTrack(0);
String[] ans = new String[set.size()];
int i = 0;
for(var st: set) ans[i++] = st;
return ans;
}
}
【优化】在交换的过程中,可能出现某个字符和后面的字符相同,这样的话只要交换一次就行了。
class Solution {
Set<String> set = new HashSet();
int n;
char[] c;
public void swap(int i, int j){
char t = c[i];
c[i] = c[j];
c[j] = t;
}
public void backTrack(int t){
if(t == n) set.add(String.valueOf(c));
else{
int[] cnt = new int[26];
for(var i = t; i < n; i++){
if(cnt[c[i] - 'a'] == 1) continue;
cnt[c[i] - 'a'] = 1;
swap(i, t);
backTrack(t + 1);
swap(i, t);
}
}
}
public String[] permutation(String s) {
c = s.toCharArray();
n = c.length;
backTrack(0);
String[] ans = new String[set.size()];
int i = 0;
for(var st: set) ans[i++] = st;
return ans;
}
}