LeetCode47 全排列2
方法:回溯法(深度优先搜索dfs+状态重置)+剪枝
关键点:剪枝(去重)
1、候选数组排序
2、通过该位置的重复元素nums[i-1]是否使用过(used[i-1]),如果used[i-1]=false,则结果重复,去重(continue)
public List<List<Integer>> permuteUnique(int[] num) {
Arrays.sort(num); //保证数组重复元素在一块,方便去重 ,所以通过排序的方式来实现它
int len = num.length;
boolean[] vis = new boolean[len];
List<List<Integer>> res =new ArrayList<List<Integer>>();
ArrayList<Integer> temp = new ArrayList<Integer>();
dfs(num, len, temp, vis, res);
return res;
}
public void dfs(int[] num,int len,ArrayList<Integer> temp,boolean[] vis,List<List<Integer>> res) {
if(temp.size() == len ) { //递归结束条件
res.add(new ArrayList<Integer>(temp));
return;
}
for(int i = 0; i < num.length; i++) { //确定该位置放那个元素
if(!vis[i]){
if(i>0 && num[i] == num[i-1] && !vis[i-1]) continue; //减枝;当执行相同元素后者时,若前一个相同元素没有被使用,则将这个位置是该元素的所有可能性给continue掉(前一个元素被使用,说明是首次的情况,若没被使用,则不是首次出现重复)
temp.add(num[i]);
vis[i] = true;
dfs(num, len, temp, vis,res); //递归,确定位置(操纵位置(深度))
vis[i] = false; //状态重置,恢复该位置元素可用性
temp.remove(temp.size()-1); //回溯
}
}
}
时间复杂度:O(n!+nlogn) ; 因为数组排序+dfs
空间复杂度:O(3len) ; res+temp+used