深搜&回溯&剪枝-全排列

LCR 083. 全排列 - 力扣(LeetCode)

根据题意,要根据给定的整数数组,穷举出所有可能的排列,从直观的角度上来看,可以使用多层 for 循环来解决,但如果是数组长度太大的时候,这种方式不太合适。

对于此类问题,要先画出决策图,例如对于数组 1,2,3 而言:


全局变量:使用全局变量会让方法调用时的参数更加简单;

  1. 使用全局变量 List 数组来存每一个符合要求的排列;

  2. 使用全局变量 List 来暂存每一次遍历的排列值;

  3. 由于需要通过剪枝来去掉一些不符合要求的情况,也就是重复出现数字的情况,因此使用全局变量 boolea\[\] 来存原始数组的值是否被使用,被使用则为1,否则为0;
    关注递归函数dfs本身:

使用for循环,结合剪枝来进行排列组合;
**回溯:**每当枚举完一个分支后,要回到分支的主节点,是需要进行回溯的,把全局变量 List 最后一个节点去掉,以及将该节点对应的 boolean\[\] 中的值由 true 改为 false;

**剪枝:**剪掉重复出现数字的情况;

**递归出口:**当全局变量 List 的长度等于原始数组的长度,说明已经存满了,就可以直接将当前的 List 存到 全局变量 List数组中;

代码实现

java 复制代码
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;
            }
        }
    }
}
相关推荐
renhongxia18 小时前
世界模型,是“空中楼阁”还是AGI的“最后一块拼图”?
运维·服务器·数据库·人工智能·算法·agi
zephyr0510 小时前
动态规划-最长上升子序列问题
算法·动态规划
闪电悠米11 小时前
力扣hot100-56.合并区间-排序详解
数据结构·算法·leetcode·贪心算法·排序算法
卡提西亚12 小时前
leetcode-1438. 绝对差不超过限制的最长连续子数组
算法·leetcode·职场和发展
Java面试题总结12 小时前
LeetCode 93.复原IP地址
算法·leetcode·职场和发展·.net
从零开始的代码生活_13 小时前
C++ 多态详解:虚函数、动态绑定、抽象类与虚表原理
开发语言·c++·后端·学习·算法
Tisfy13 小时前
LeetCode 3867.数对的最大公约数之和:按题目说的做(gcd)
算法·leetcode·题解·模拟·最大公约数·gcd
泷寂13 小时前
最小生成树 (MST基础)
算法
Daniel_12313 小时前
数组——总结篇
算法
不懒不懒14 小时前
【针对路面识别数据集,结合三轴加速度标准化数据及多路面识别需求,以下是算法选择与处理方案】
算法