目录
题目:
题目描述:

题目链接:
思路:
核心思路:
dfs
思路详解:
根据全排列和示例我们可以画出如下的搜索树

通过搜索树我们能更好的理解如何使用dfs的具体逻辑来完成题目,因为是全排列,nums里面的每一个数不会重复出现排列,所以我们可以定义布尔类型used数组来标记某个数是否被用过。dfs的参数u表示现在在选第u位数,u从0开始。每次选数时遍历所有数,看哪个数没被用过,选择没用过的数加入到list当中后把该数used标记为true,然后dfs(u+1)继续枚举下一个位置的数。回溯的时候注意恢复现场。dfs的结束条件就是u==n,表明这是其中一个合法的排列,然后将list加入到res中。
这里有两个实际编码容易出错的地方:1、nums是permute方法的参数,在dfs方法中无法直接访问。有两种处理方式一个是将nums作为类的成员变量,另一个是在dfs中传递nums 2、在将list加入res时,不是直接res.add(list)而是res.add(new ArrayList<>(list))新建一个List,不然会出现引用问题
代码:
Java代码:
class Solution {
private int n;
private boolean[] used; //默认为false,即所有数都没有被用过
private List<Integer> list = new ArrayList<>();
private List<List<Integer>> res = new ArrayList<>();
private int[] nums; //要么将nums作为成员变量,要么将nums作为参数传递给dfs
public List<List<Integer>> permute(int[] nums) {
this.n = nums.length;
this.used = new boolean[n];
this.nums = nums;
dfs(0);
return res;
}
public void dfs(int u) //u表示现在在选第u位数,u从0开始
{
if(u == n)
{
res.add(new ArrayList<>(list)); //避免引用问题,新建一个List
return;
}
for(int i=0;i<n;i++)
{
if(!used[i]) //如果某个数没被用过
{
list.add(nums[i]); //选择这个数排列,加入到list中
used[i] = true; //将该数used标记改为true
dfs(u+1); //继续枚举下一个位置的数
list.remove(list.size()-1); //回溯,移除最后一个元素
used[i] = false; //回溯,恢复现场
}
}
}
}