第25-26天学习笔记——递归、二叉树DFS、BFS

  • 递归
    • 递归代码的组成部分:
      • 递归终止条件
      • 递归代码
      • 递归后的代码
      • 返回的结果
    • 递归的本质和基本实现方式
      • 1、函数通过自身调用自身
      • 2、通过函数体来进行的循环,递归通常不在意具体操作,只关心初始条件和上下层的变化关系。
      • 3、递归函数需要有临界停止点,即递归不能无限制的执行下去。通常这个点为必须经过的一个数。

      • 有点像栈,先处理倒数第一个函数,再把倒数第一个的输出放到倒数第二个函数里,继续处理

    • 递归思想
      • 递归算法,顾名思义就是有两个大的阶段:递和归,即就是有去(递去)有回(归来)。
        • 递去:将递归问题分解为若干个规模较小,与原问题形式相同的子问题,这些子问题可以用相同的解题思路来解决
        • 归来:当你将问题不断缩小规模递去的时候,必须有一个明确的结束递去的临界点(递归出口),一旦达到这个临界点即就从该点原路返回到原点,最终问题得到解决。
      • 设计思路
        • 明确递归的终止条件
        • 提取重复的逻辑,缩小问题的规模不断递去
        • 给出递归终止时的处理办法

        • 设计递归函数的步骤
        • 1. 给递归函数一个明确的定义。
        • 2. 实现边界条件时的程序逻辑。
        • 3. 假设递归函数调用返回结果是正确的,实现本层函数逻辑。
          • 例如:计算n的阶乘:假设f(n-1)就是正确的返回n-1的阶乘,如何实现f(n)的阶乘呢?很简单的公式:f(n)=f(n-1)*n。
      • 使用递归的问题
        • ①数据的定义是按递归定义的,如阶乘、斐波那契数列
        • ②问题解法按照递归算法实现,如汉诺塔
        • ③数据的结构形式按递归定义,如二叉树
      • LeetCode 206、反转链表(最经典)
        • 法一递归:
          • 1、通过递归函数,一直递归到链表的最后一个结点为止,此时,该结点就是反转成功后的头结点,是最终的返回结果。
          • 2、在递归函数中,让当前节点的下一个节点的 next 指针指向当前节点。
          • 3、在递归函数中,让当前节点的 next 指针指向 null
          • 4、通过2,3步的操作,已经让递归函数中的链表实现了局部反转,将结果返回给上一层递归函数
          • 5、所有递归结束后,链表反转成功。
        • 法二双指针:
  • 二叉树的 DFS、
    • 二叉树
      • 「二叉树Binary Tree.是一种非线性数据结构,代表着祖先与后代之间的派生关系,体现着“一分为二"的分治逻辑。
      • 类似于链表,二叉树也是以结点为单位存储的,结点包含「值」和两个「指针」。
      • 二叉树定义
        • 注意二叉树的高度定义

      • 二叉树的前、中、后序遍历
    • DFS 思路
      • 1、创建结果存储变量,初始当前结果
      • 2、设计递归函数,函数执行过程如下:
        • a、如果到达结尾,则返回
        • b、如果没有到达结尾,则更新当前结果
        • c、如果到达末尾叶子结点,对比进行结果更新,取最优解
        • d、分别对当前结点的左、右叶子结点调用递归函数
      • 3、开始调用递归函数
    • LeetCode 104、二叉树的最大深度
      • 递归调用
        • 终止条件:如果 root 为空,直接返回 0
        • 子问题:分别调用递归,求当前节点左、右子树的最大深度
        • 当前节点的最大深度就是它的左右子树中较大的值加上 1
    • LeetCode 111 、二叉树的最小深度
      • 这个如果按照上面的最大深度做可能出错,因为可能出现左子树不为空,右子树为空的情况,这种情况下,最小深度不是右子树的0,而是需要计算有叶子节点的左子树的深度,所以需要加上一个判断
    • LeetCode 226、翻转二叉树
      • 递归终止条件
      • 递归代码:对左子树进行翻转,对右子树进行翻转
      • 递归后代码:翻转
      • 返回结果:root
  • 二叉树的 BFS
    • 万金油算法
    • 搜索就是采用直接遍历整个状态空间的方式寻找答案的一类算法。
    • 深度优先搜索:一条道走到黑
    • 广度优先搜索:逐层遍历
    • 无论是哪种搜索,每个状态只遍历一次

    • LeetCode 102、二叉树的层序遍历
      • 层序遍历的过程

      • 需要借助队列实现
      • 遍历队列,直到队列为空,说明访问了二叉树中所有的节点
      • 判断队列有多少个元素,决定多少个元素是一组的

      • 把当前节点弹出,它的左右子树都是它的下一层(左右子树在同一层),压入队列
  • 【DFS/BFS】2023B-树状结构查询(二叉树实际应用 ——> 如何建树+查询)(重点)
    • 首先使用哈希表构建邻接表children_dict,对输入进行建树处理,即

    • DFS解法
      • 对每个节点的child进行递归遍历

    • BFS解法
      • 用队列对每一层进行遍历

    • 时间复杂度:O(N)。无论是DFS还是BFS,最差的情况都是遍历整棵树。
    • 空间复杂度:O(N)。children_dict所占用空间。
  • 第二十六天(作业)
    • 简答题
      • 你能否使用BFS算法完成题目LeetCode 104、二叉树的最大深度 和 LeetCode 111 、二叉树的最小深度
        • LeetCode 104、二叉树的最大深度 BFS解法
          • 首先压入root节点(如果root不等于None),高度+1(高度初始为0),然后获取队列长度n,执行n次对每个节点左子树和右子树是否压入的操作(操作后删除当前节点),执行n遍后这一层节点全部删除;此时再次获取队列的长度,此长度即为新的当前一层节点个数,如果n_new等于0,则表示上一层已全部为叶子节点,终止操作返回结果,如果n大于0,高度+1,重复之前的操作

        • LeetCode 111 、二叉树的最小深度 BFS解法
          • 通过队列来逐层遍历二叉树,一旦发现某个树节点既没有左子树和右子树,那么直接返回即可

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值