题目:
给定一个不含重复数字的数组nums
,返回其所有可能的全排列 。你可以按任意顺序返回答案。
思路:
方法:深度优先搜索(DFS)+回溯
- 可以设置一个状态变量数组
used[]
,默认值为0时,表示该索引对应的值没有被遍历过,如果为1,表示已经遍历过,这样只用O(1)的时间复杂度就能找到该数是否可用,典型的拿空间换时间
- 因为是数组的全排列,因此我们每次遍历一个数时,就在当前状态的基础上对数组进行遍历,设置一个
集合res
来存储所有的可选情况,动态集合cur
来存储当前的情况 - 设置一个变量
index
表示当前遍历到的数组位置,从0开始一直到结尾,如果出现index==arr.length
的情况,说明走到了尽头,将这时的集合cur
添加到res集合
中,并return
返回进行回溯 - 等到所有情况都遍历完,最后的
res集合
就是最终结果
以下为代码+注释:
// 设置一个res集合存放最后结果
private List<List<Integer>> res = new ArrayList<List<Integer>>();
// 设置一个cur集合存放当前遍历情况呢
private List<Integer> cur = new ArrayList<>();
// 设置一个状态变量,如果数组中一个值遍历过,就将他的索引位置在该数组中的值置为1
// 默认为0,也就是当前值对应的索引还没有遍历过
private int[] used;
public List<List<Integer>> permute(int[] nums) {
used = new int[nums.length];
dfs(nums, 0);
return res;
}
public void dfs(int[] arr, int index){
// 边界情况
if(index == arr.length){
res.add(new ArrayList(cur));
return;
}
for(int i = 0; i < arr.length; i++){
// 如果该数没有遍历过,就可以加入
if(used[i] == 0){
used[i] = 1;
cur.add(arr[i]);
dfs(arr, index + 1);
// 回溯,也就是状态重置,回到刚进入循环时候的状态查找其他情况的排列
cur.remove(cur.size() - 1);
used[i] = 0;
}
}
}
笔者也在不断学习中,如有错误,欢迎指正!