LCR 083. 全排列 - 力扣(LeetCode)
根据题意,要根据给定的整数数组,穷举出所有可能的排列,从直观的角度上来看,可以使用多层 for 循环来解决,但如果是数组长度太大的时候,这种方式不太合适。
对于此类问题,要先画出决策图,例如对于数组 [1,2,3] 而言:
全局变量:使用全局变量会让方法调用时的参数更加简单;
1. 使用全局变量 List 数组来存每一个符合要求的排列;
2. 使用全局变量 List 来暂存每一次遍历的排列值;
3. 由于需要通过剪枝来去掉一些不符合要求的情况,也就是重复出现数字的情况,因此使用全局变量 boolea[] 来存原始数组的值是否被使用,被使用则为1,否则为0;
关注递归函数dfs本身:
使用for循环,结合剪枝来进行排列组合;
回溯:每当枚举完一个分支后,要回到分支的主节点,是需要进行回溯的,把全局变量 List 最后一个节点去掉,以及将该节点对应的 boolean[] 中的值由 true 改为 false;
剪枝:剪掉重复出现数字的情况;
递归出口:当全局变量 List 的长度等于原始数组的长度,说明已经存满了,就可以直接将当前的 List 存到 全局变量 List数组中;
代码实现
class Solution {
List<List<Integer>> ret;
List<Integer> str;
boolean[] judge;
public List<List<Integer>> permute(int[] nums) {
ret = new ArrayList<>();
str = new ArrayList<>();
judge = new boolean[nums.length];
dfs(nums);
return ret;
}
public void dfs(int[] nums){
if(str.size() == nums.length){
ret.add(new ArrayList(str)); // 递归出口:符合条件。直接add
}
for(int i=0;i<nums.length;i++){
if(judge[i] == false){ // 剪枝,boolean如果是true说明出现过了,就不再进入了
str.add(nums[i]);
judge[i] = true;
dfs(nums); // 继续递归
// 回溯:将最后一个值去掉,boolean改为false
str.remove(str.size()-1);
judge[i] = false;
}
}
}
}