这里总共有三个数组:
其中两个数组是定长数组,另一个数组是可变数组
nums数组是我们要进行全排列的数组,与之配套的是flag数组,用来标记nums数组中每个元素是否被添加到chosed数组中(nums数组就是选择列表,需要遍历选择列表里面的每一个元素)
chosed数组是一个可变数组,等它的长度长到了nums数组的长度,说明一个排列完成了,就把此时的chosed数组添加到最终的结果数组中(这个chosed数组也被称为路径)
class Solution
{
//定义出三个数组
ArrayList<ArrayList<Integer>> result = new ArrayList<>();
// 记录数组,这个数组里面的数表示已经被选中了,后面不能再选这里面存在的数了
ArrayList<Integer> chosed = new ArrayList<>();
boolean[] flag;
//传入要进行全排列的数组
ArrayList<ArrayList<Integer>> permute(int[] nums)
{
//chosed数组中已经存在的数会被标记为 true,其他没有使用过的数标记成false
flag = new boolean[nums.length];
//传入三个参数:要进行全排列的数组,chosed数组(里面存了已经选择过了的数),flag数组
dfs(nums, chosed, flag);
return result;
}
void dfs(int[] nums, ArrayList<Integer> chosed, boolean[] flag)
{
// 触发结束条件
if (chosed.size() == nums.length)
{
result.add(new ArrayList<>(chosed));
return;
}
for (int i = 0; i < nums.length; i++)
{
//遍历flag数组,如果已经被选中添加到chosed数组里,就下一个数
if (flag[i]==true)
{
continue;
}
//如果flag[i]==false,说明这个数没有被添加到chosed数组里面
else
{
//把这个数加到chosed数组里面
chosed.add(nums[i]);
//将这个数的标志位置为true,表示已经被加到chosed数组里面了
flag[i] = true;
// 递归,进入下一层决策树
dfs(nums, chosed, flag);
// 下面恢复现场,将刚刚加入的数弹出去,相应的标志位也置为false,表示没有添加到chosed数组里
chosed.remove(chosed.size()-1);
flag[i] = false;
}
}
}
}
public class test
{
public static void main(String[] args)
{
int[] nums={1,2,3,4,5};
Solution a=new Solution();
System.out.println(a.permute(nums));
}
}
回溯的模板:
result = []
dfs(路径, 选择列表)
{
if 满足结束条件:
result.add(路径)
return
for 选择 in 选择列表:
做选择
backtrack(路径, 选择列表)
撤销选择
}
总结: