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

摄影后期教程网站网络营销与策划

摄影后期教程网站,网络营销与策划,风铃做的网站能否推广,网站建设是用自己的服务器文章目录 一、题目介绍二、递归思路详解:从决策树开始理解三、解法一:二叉决策树 DFS四、解法二:组合式回溯写法(推荐)五、解法对比 递归算法是编程中一种非常强大且常见的思想,它能够优雅地解决很多复杂的…

文章目录

  • 一、题目介绍
  • 二、递归思路详解:从决策树开始理解
  • 三、解法一:二叉决策树 DFS
  • 四、解法二:组合式回溯写法(推荐)
  • 五、解法对比

递归算法是编程中一种非常强大且常见的思想,它能够优雅地解决很多复杂的问题,比如树的遍历、组合问题、回溯搜索等。

今天,我们以 LeetCode 第 78 题「子集(Subsets)」为例,带大家深入理解递归的思路、实现细节以及不同写法的差异。

一、题目介绍

题目链接: 78. 子集 - LeetCode

题目描述:
给定一个整数数组 nums,返回该数组所有可能的子集(幂集)。

示例:

输入: nums = [1,2,3]
输出: [[], [1], [2], [3], [1,2], [1,3], [2,3], [1,2,3]]

二、递归思路详解:从决策树开始理解

我们用递归的方式去“做决策”——对每个元素,都面临两个选择:

  • 选择它
  • 不选择它

这种决策结构,其实就像是一棵二叉树:
每一个节点都有两个分支,一个是“我选了当前元素”,另一个是“我跳过当前元素”。

举例说明

nums = [1, 2] 为例,整个决策过程如下所示:

                []/    \[1]     []/   \      \[1,2]   [1]     [2]

每一条路径就是一个子集的构建过程:

  • []:什么都不选
  • [1]:只选第一个
  • [1,2]:全选
  • [2]:只选第二个

最终收集所有路径,就是所有的子集

用语言描述递归过程

  • 从位置 0 开始:
    • nums[0],进入下一层递归
    • nums[1],递归到尽头,保存 [1,2]
    • 不选 nums[1],保存 [1]
  • 不选 nums[0]
    • nums[1],保存 [2]
    • 不选 nums[1],保存 []

这样,我们就得到了所有子集。

三、解法一:二叉决策树 DFS

解法思路
每次递归考虑一个元素,选或不选。
当走到数组末尾时,当前构建的路径就是一个合法的子集。

class Solution 
{vector<vector<int>> ret;  // 存放结果集vector<int> path;         // 当前构建的子集路径
public:vector<vector<int>> subsets(vector<int>& nums) {dfs(nums, 0);         // 从索引 0 开始递归return ret;}void dfs(vector<int>& nums, int pos){if (pos == nums.size()) // 递归出口:遍历完所有元素{ret.push_back(path); // 加入当前路径return;}// 选择当前元素path.push_back(nums[pos]);dfs(nums, pos + 1);path.pop_back(); // 回溯,撤销选择// 不选择当前元素dfs(nums, pos + 1);}
};

四、解法二:组合式回溯写法(推荐)

思路核心
我们从当前下标 pos 开始向后遍历,每次选一个元素加入 path,递归处理后续子集,不再考虑当前之前的元素,避免重复。

这种方式更像是“组合问题”的模板写法。

决策过程

  • 每进入递归一次,就把当前 path 加入结果集
  • 然后,从当前位置 pos 开始遍历,尝试将每个元素加入 path,并递归后续
  • 回溯:递归返回后,需要把最后加入的元素移除,恢复现场

举例说明

                           []┌───────────────┼────────────────┐[1]              [2]             [3]/     \          /     \             \[1,2]   [1,3]     [2,3]                  [3]|        |         |[1,2,3]  [1,3]     [2,3]

用语言描述过程
pos = 0 开始:

  1. 先将空集 [] 加入结果集。
  2. 遍历索引 0~2:
    • 选择 nums[0]=1,路径变为 [1]
      • 继续从 pos=1 开始遍历:
        • 2 -> [1,2]
          • 3 -> [1,2,3]
        • 回溯到 [1]
        • 3 -> [1,3]
    • 回溯回到 []
    • 2 -> [2]
      • 3 -> [2,3]
    • 回溯回到 []
      • 3 -> [3]
        每一步都把当前的路径保存下来,形成最终的子集集合。

代码实现

class Solution 
{vector<vector<int>> ret;vector<int> path;
public:vector<vector<int>> subsets(vector<int>& nums) {dfs(nums, 0); // 从第 0 个元素开始扩展return ret;}void dfs(vector<int>& nums, int pos){ret.push_back(path); // 每个路径都是一个合法子集for (int i = pos; i < nums.size(); i++){path.push_back(nums[i]);dfs(nums, i + 1);   // 继续递归下一个元素path.pop_back();    // 回溯,移除当前元素}}
};

优点分析

  • 不需要写递归出口,利用 for 循环自动控制终止条件
  • 结构上类似「组合问题」的回溯模板

为什么说它更像‘组合问题’?
因为组合问题也遵循一个核心原则:

  • 每次只能向后选元素,不能回头,以防止重复。

比如要从 [1,2,3] 中选出长度为 2 的组合,这种“向后递归 + 回溯”的结构是最自然的选择。

五、解法对比

比较维度解法一(选/不选)解法二(组合式回溯)
决策方式二分支:选 or 不选枚举所有起点及其后续路径
是否需要出口判断是(pos == nums.size()否,for 控制终止
可读性模拟决策树,结构清晰更接近组合枚举的写法
常见用途子集、排列、二叉树类问题子集、组合、N 皇后等问题
http://www.dtcms.com/wzjs/821409.html

相关文章:

  • 商城网站的开发怎么做WordPress 文章模板制作
  • 信息化建设包括网站建设小程序首页模板
  • 营销类网站如何优化龙华品牌网站建设
  • 苏州建网站要多少钱东莞软文推广
  • wordpress 网站建设中学生个人网页制作代码
  • 社交网站建设需求分析通过电子邮件发布 wordpress
  • 凯叔讲故事网站谁做的网站建设需求分析怎么写
  • 网站在哪里设置关键字wordpress速度快
  • 专业展示设计网站老年大学网站开发
  • 上海网站建设极简慕枫贷款网站建设方案
  • AD这个软件做网站用得着吗区块链开发用什么语言
  • 网站怎么做才被收录快做网站需要学什么软件
  • 网站如何添加代码理县网站建设公司
  • 手机网站建设基本流程石材公司网站源码
  • 大连网站建设怎么样门户媒体有哪些
  • 快速免费建网站河南省建设厅建筑业信息网
  • 活动策划公司网站wordpress 模板安装
  • 做h5小程序的网站直播视频
  • 哪里有零基础网站建设教学公司wordpress rss静态化
  • 长沙网站seo源头厂家时空seo助手
  • 苏州网站小程序app开发公司android软件开发前景
  • 网站首页图片切换美橙互联
  • 安康市网站开发字节跳动小程序官网
  • 门户网站系统开发自己建站流程
  • 嘉兴做网站优化的公司263企业邮箱手机入口登录
  • 建站平台 阿里巴巴公众号开发者平台
  • 浪琴女士手表网站连平网站建设
  • 阜宁网站建设服务商装饰公司网站建设流程
  • 北京微网站建设设计服务公司自己设计网页作业的感悟
  • 网站开发的合同编写金汇网站建设