给定一个没有重复数字的序列,返回其所有可能的全排列。
示例:
输入: [1,2,3]
输出:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
思路 回溯法
有点看不懂 递归的过程
public class Solution {
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
if (nums.length== 0) return res;
boolean[] used = new boolean[nums.length];
List<Integer> path = new ArrayList<>();
dfs(nums, 0 , path, used, res);
return res;
}
private void dfs(int[] nums, int depth,
List<Integer> path, boolean[] used,
List<List<Integer>> res) {
if (depth == nums.length) {
res.add(new ArrayList<>(path));
return;
}
for (int i = 0; i < nums.length; i++) {
if (!used[i]) {
path.add(nums[i]);
used[i] = true;
dfs(nums, depth + 1, path, used, res);
// 注意:这里是状态重置,是从深层结点回到浅层结点的过程,代码在形式上和递归之前是对称的
used[i] = false;
path.remove(depth);
}
}
}
}
lee47 全排列除去重复的
注:这题跟上一题不一样的点就是:不能有重复,可以先排序 如果这次的跟上次一样就剪枝,注意是一棵树同一层的情况,如果是深度看的话可以相同
/一定要多加一个nums[i-1]的判断,因为剪枝是剪得刚刚深度优先遍历撤销选择
if(i>0 && nums[i]==nums[i-1] && nums[i-1]==0) continue;
class Solution {
public List<List<Integer>> permuteUnique(int[] nums) {
List<List<Integer>> res=new ArrayList<>();
if(nums==null||nums.length==0) return res;
int[] flag=new int[nums.length];
Arrays.sort(nums);
helper(nums,0,new ArrayList<>(),res,flag);
return res;
}
private void helper(int[] nums,int start,List<Integer> list,List<List<Integer>> res, int[] flag){
if(start==nums.length){
res.add(new ArrayList<>(list));
return;
}
for(int i=0;i<nums.length;i++){
if(flag[i]==1) continue;
//一定要多加一个nums[i-1]的判断,因为剪枝是剪得刚刚深度优先遍历撤销选择
if(i>0 && nums[i]==nums[i-1] && nums[i-1]==0) continue;
list.add(nums[i]);
flag[i]=1;
helper(nums,start+1,list,res,flag);
flag[i]=0;
list.remove(list.size()-1);
}
}
}