原题:点击此处
考点:
字符串、回溯
思路:
- 本道题很容易就想到是回溯,难点是怎么实现回溯。
- 对于字符串这个字符性质,用列表来进行不断地remove好像不太合适,因此本题采用的方法是:
在当前位置的字符,不断地与后面的字符进行交换,当做完操作后,再换回来。
- 而且要实现一个HashSet,这个原因是因为有可能会有这样的[a,a,c,v,b]这样的列表,其中a是有重复的,如果不用HashSet的话,就会出现重复。
时间复杂度O(n!)(因为排列方案就是n × (n-1)× (n-2)……)
空间复杂度O(n2) (因为HashSet的对象一直在创建,是n + (n-1)+ (n-2)……)
class Solution {
ArrayList<String> ans = new ArrayList<>();
char[] c;
public String[] permutation(String s) {
c = s.toCharArray();
dfs(0);
return ans.toArray(new String[ans.size()]);
}
public void dfs(int x){
if(x == c.length-1){
ans.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(c,i,x);
dfs(x+1);
//交换回来
swap(c,i,x);
}
}
public void swap(char[] c,int i,int j){
char temp = c[i];
c[i] = c[j];
c[j] = temp;
}
}