解决回溯问题,需要考虑三个问题:1、路径:已经做出的选择。2、选择列表:你可以做出的选择。3、结束条件。
模板如下:
List<类型> result = new ArrayList<>();
dfs(选择){
if 满足结束条件
result.add(路径)
for(选择列表做选择){
做选择
dfs(往下遍历)
撤销选择
}
}
leetcode47题全排列二
List<List<Integer>> result = new LinkedList<>();
public List<List<Integer>> permuteUnique(int[] nums) {
LinkedList<Integer> track = new LinkedList<>();
boolean []visited = new boolean[nums.length];
//nums必须排序,过滤掉重复的组合
Arrays.sort(nums);
backtrack(nums,visited,track);
return result;
}
public void backtrack(int []nums,boolean []visited,LinkedList<Integer> track){
if(track.size() == nums.length){
result.add(new LinkedList<>(track));
return ;
}
for(int i = 0; i < nums.length; i++){
if(visited[i])
continue;
//如果当前数nums[i]和前一个数nums[i - 1]相同,
//并且前一个数nums[i - 1]在之前的递归层未被选择过,也跳过
//比如对于[1, 2', 2'', 3]数组,假设我们已经选择了1,
//track变成了[1];然后进入了下一层递归,要从[2', 2'', 3]三个数
//里面选一个数作为track的第二个元素,那对于这两个2只要选一个就行,
//也就是选择2'就行,2''需要被跳过,即如果前一个相同的没选,
//后一个直接跳过
if(i > 0 && nums[i-1] == nums[i] && !visited[i-1])
continue;
visited[i] = true;
track.add(nums[i]);
backtrack(nums,visited,track);
visited[i] = false;
track.removeLast();
}
}