解题思路:
回溯法,有大佬总结了回溯法的模板,在这里借用,链接:回溯法
在递归之前做选择,在递归之后撤销选择
其中,全排列2用到了剪枝
全排列1
class Solution {
List<List<Integer>> res = new LinkedList<>();
public List<List<Integer>> permute(int[] nums) {
//记录路径
List<Integer> track = new LinkedList<>();
//回溯
backtrack(nums, track);
return res;
}
public void backtrack(int[] nums, List<Integer> track){
//停止回溯的条件->路径包含所有元素
if(track.size() == nums.length){
res.add(new LinkedList(track));
return;
}
for(int i = 0 ; i < nums.length; i++ ){
//路径中已经包含该元素则跳过
if(track.contains(nums[i])){
continue;
}
//选择,加入一个未包含的元素加入路径
track.add(nums[i]);
//进入下一层决策树
backtrack(nums, track);
//取消选择,移除元素
track.remove(track.size()-1);
}
}
}
全排列2
class Solution {
List<List<Integer>> res = new LinkedList<>();
boolean[] isvisited;
public List<List<Integer>> permuteUnique(int[] nums) {
List<Integer> track = new LinkedList<>();
isvisited = new boolean[nums.length];
Arrays.sort(nums);
backtrack(nums, isvisited, track);
return res;
}
public void backtrack(int[] nums, boolean[] isvisited, List<Integer> track){
if(track.size() == nums.length){
res.add(new LinkedList(track));
return;
}
for(int i = 0 ; i < nums.length; i++ ){
if(isvisited[i]){
continue;
}
if(i > 0 && nums[i]==nums[i-1] && isvisited[i-1]){
continue;
}
track.add(nums[i]);
isvisited[i] = true;
backtrack(nums, isvisited, track);
track.remove(track.size()-1);
isvisited[i]= false;
}
}
}