当前位置: 首页 > news >正文

穷举 vs 暴搜 vs 深搜 vs 回溯 vs 剪枝

穷举 vs 暴搜 vs 深搜 vs 回溯 vs 剪枝

  • 1. 全排列
  • 2. 子集

1. 全排列

题目链接:46. 全排列

算法原理:

  1. 画出决策树
    在这里插入图片描述

  2. 设计函数

  • 全局变量:二维数组ret存储结果;一维数组path存储路径;boolean类型一维数组visited表示当前节点是否已经被使用
  • 深度优先遍历dfs,当某个节点被使用后,标记为true
  • 剪枝:当某个节点已经被使用过时,该分支剪掉
  • 回溯:visited[i] 回溯为 false,path的最后一个元素删除
  • 递归的出口:当path的大小和nums的大小相等时,将path存入ret中,并返回

实现代码:

class Solution {
    public List<List<Integer>> ret;
    public List<Integer> path;
    boolean[] visited;
    public List<List<Integer>> permute(int[] nums) {
        ret = new ArrayList<>();
        path = new ArrayList<>();
        visited = new boolean[nums.length];
        dfs(nums);
        return ret;
    }

    private void dfs(int[] nums) {
        if(path.size() == nums.length) {
            //将路径添加进结果中
            ret.add(new ArrayList<>(path));
            return;
        }
        for(int i = 0; i < nums.length; i++) {
            //当当前节点未使用时
            if(!visited[i]) {
                path.add(nums[i]);//添加当前节点到路径中
                visited[i] = true;//标记当前节点已经使用
                dfs(nums);
                //回溯
                visited[i] = false;
                path.remove(path.size() - 1);
            }
        }
    }
}

2. 子集

题目链接:78. 子集

算法流程:
解法一:

  1. 画出决策树:以数组[1, 2, 3]为例,对每个元素分为不选两种操作
    在这里插入图片描述由此可知,决策树的叶子节点就是该数组的子集

  2. 设计代码

  • 全局变量:一维数组path存储所经过的路径,二维数组ret存储所得的结果
  • dfs:函数头dfs(int[] nums, int i),分为选择nums[i]和不选择nums[i],选择nums[i]所需进行的操作为path尾部加入nums[i]。并dfs(nums, i+1);不选择nums[i]所需进行的操作为dfs(nums, i+1)
  • 细节问题:剪枝,回溯,递归出口。这道题不需要剪枝;回溯操作为删除path尾部的元素;递归出口为i == nums.length,将该路径存到ret中,返回

实现代码:

class Solution {
    public List<Integer> path;
    public List<List<Integer>> ret;
    public List<List<Integer>> subsets(int[] nums) {
        path = new ArrayList<>();
        ret = new ArrayList<>();
        dfs(nums, 0);
        return ret;
    }
    private void dfs(int[] nums, int i) {
        if(i == nums.length) {
            ret.add(new ArrayList<>(path));
            return;
        }

        dfs(nums, i+1);
        
        path.add(nums[i]);
        dfs(nums, i+1);
        path.remove(path.size()-1);
    }
}

解法二:
算法流程:

  1. 画出决策树:以数组[1, 2, 3]为例,分为选择0,1,2,3个元素
    在这里插入图片描述
    在进行下一步选择元素时,只能去选择上一步所选元素后面的元素

  2. 设计代码

  • 全局变量:一维数组path存储所经过的路径,二维数组ret存储所得的结果
  • dfs:函数头dfs(int[] nums, int pos),pos代表上一步所选元素后面一个元素的下标
  • 细节问题:回溯,即删除path尾部的元素

实现代码:

class Solution {
    public List<Integer> path;
    public List<List<Integer>> ret;
    public List<List<Integer>> subsets(int[] nums) {
        path = new ArrayList<>();
        ret = new ArrayList<>();
        dfs(nums, 0);
        return ret;
    }
    private void dfs(int[] nums, int pos) {
        ret.add(new ArrayList<>(path));
        for(int i = pos; i < nums.length; i++) {
            path.add(nums[i]);
            dfs(nums, i+1);
            path.remove(path.size()-1);
        }
    }
}

相关文章:

  • 基于Flask的广西高校舆情分析系统的设计与实现
  • 《Nuxt.js 实战:从放弃到入门》六、打造个性化文字转图片工具
  • 各类系统Pycharm安装教程
  • MongoDB between ... and ... 操作
  • Android嵌套滑动造成的滑动冲突原理分析
  • 解惑Python:一文解决osgeo库安装失败问题
  • DeepSeek + Vue实战开发
  • Python字符模糊匹配指南 RapidFuzz | python小知识
  • RocketMQ 5.0安装部署
  • Ubuntu 安装 OpenCV (C++)
  • 请解释设备像素、CSS 像素、设备独立像素、DPR、PPI 之间的区别 ?
  • 将图片base64编码后,数据转成图片
  • Jetson Agx Orin平台preferred_stride调试记录--1924x720图像异常
  • SQL代码规范
  • 外贸跨境订货系统流程设计、功能列表及源码输出
  • 数据结构:单链表(Single Linked List)及其实现
  • 奥比中光3D机器视觉相机能连接halcon吗?
  • 基于海思soc的智能产品开发(图像处理的几种需求)
  • LeetCode每日精进:20.有效的括号
  • 【Go语言快速上手】第二部分:Go语言进阶之网络编程
  • 东莞seo整站优化/seo长尾关键词
  • 车轮违章查询是什么网站开发/产品软文
  • 武汉值得去的互联网公司/北京快速优化排名
  • 西宁手机网站建设/商品推广软文范例300字
  • 上海快速建站/百度问答app下载
  • 郑州最好的网站建设/汕头网站排名