回溯算法的框架
for 选择 in 选择列表:
# 做选择
将该选择从选择列表移除
路径.add(选择)
backtrack(路径, 选择列表)
# 撤销选择
路径.remove(选择)
将该选择再加入选择列表
class Solution {
List<List<Integer>> res = new ArrayList<>();
public List<List<Integer>> permute(int[] nums) {
if(nums.length == 0) return res;
// 保存路径的变量
LinkedList<Integer> path = new LinkedList<>();
// 数组的元素是否被使用,也可以使用路径是否已经包含这个元素来进行剪枝
boolean[] used = new boolean[nums.length];
// 递归
backtrack(nums, 0, path, used);
return res;
}
public void backtrack(int[] nums, int depth, LinkedList<Integer> path, boolean[] used){
// 深度等于数组的长度,就需要保存一次结果
if(depth == nums.length){
// 创建一个新的结果集保存 一定要new,而不是直接add
res.add(new ArrayList<>(path));
return;
}
// 循环里进行递归
for(int i = 0; i < nums.length; i++){
// 判断元素是否已经选择,如果有则剪枝
if(used[i]) continue;
// 递归前 选择/添加
path.addLast(nums[i]);
used[i] = true;
// 递归
backtrack(nums, depth + 1, path, used);
// 递归后还原
path.removeLast();
used[i] = false;
}
}
}