- 思想:典型的全排列问题,一般就采用DFS,且每次都从头开始做选择然后再结合visited[],不是全排序一般可以加start索引,用于控制顺序
这题重要的一点是如何去重:
记住这么一个操作:可以先对待求排列的序列进行排序,然后再保证他们再同一层上不会相同元素即可也就是
每轮做选择之前加这么一个判定
//这里的idx根据实际情况来取,如果是全排列是idx就为0其他的化idx就为start
//注意去重条件之一是!visited[i-1]而不是visited[i-1],因为前面那个保证同一层上不会出现相同元素,后面那个是保证不同层上不会出现相同元素(用于保证一个序列中不出现相同元素),而我们想要的是同一层上不出现相同元素,只有这样构造出来的排列才不会出现重复的情况
if(i>idx&&s[i]==s[i-1]&&!visited[i-1]){
continue;
}
还有一点就是如果无法提前知道结果的个数,那么我们先可以借助集合来存储 结果,然后再将其转化为数组
class Solution {
List<String> list = new ArrayList<>();
public void helper(char[] s,StringBuilder sb,boolean[] visited){
if(sb.length()==s.length){
list.add(sb.toString());
return;
}
//选择
for(int i=0;i<s.length;i++){
if(!visited[i]){
//去重
if(i>0&&s[i]==s[i-1]&&!visited[i-1]){
continue;
}
//做本次选择
sb.append(s[i]);
visited[i] = true;
helper(s,sb,visited);
//取消本次选择
visited[i] = false;
sb.deleteCharAt(sb.length()-1);
}
}
}
public String[] permutation(String s) {
int len = s.length();
if(len==0) return new String[0];
StringBuilder sb = new StringBuilder(len);
boolean[] visited = new boolean[len];
char[] c = s.toCharArray();
//使用这种方式进行排列去重时,必须先保证原序列有序!!!!
Arrays.sort(c);
helper(c,sb,visited);
return list.toArray(new String[0]);
}
}