第四课:递归、分治【C++】

递归recursion(实现形式)

函数自身调用自身
通过函数体来进行循环
以相似的方法重复进行的过程

例子:

def factorial(n):
    # 要注意边界
    if n <= 1:
        return 1
    return n * factorial(n - 1)
第四课:递归、分治【C++】_第1张图片 第四课:递归、分治【C++】_第2张图片

递归的三个关键

  • 定义需要递归的问题(重叠子问题)——数学归纳法
  • 确定递归边界
  • 保护与还原现场
    全局变量要还原,局部变量不用

分治(算法)

把原问题划分为若干个子问题,分别解决后,再把结果合并
关键点

  1. 原问题和各个子问题都是重复的(同类的)————递归定义
  2. 除了向下递归“问题”,还要向上合并“结果”

分治算法一般用递归实现
划分子问题标准:第一个子问题,作为不可分割的整体

实战

78 子集个数https://leetcode-cn.com/problems/subsets/

  • 不理解

77 组合https://leetcode-cn.com/problems/combinations/submissions/

46 全排列https://leetcode-cn.com/problems/permutations/

二叉树:
226 翻转二叉树https://leetcode-cn.com/problems/invert-binary-tree/

  1. 边界:root == null
  2. 左孩子等于右孩子,右孩子等于左孩子
  3. 翻转左节点,翻转右节点

98 验证二叉搜索树https://leetcode-cn.com/problems/validate-binary-search-tree/

  1. 边界:root == null返回0
  2. root大于左子树所有节点小于右子树所有节点(每次都要更新范围),返回true。
    根据 BST的定义,root节点需要做的不只是和左右子节点比较,而是要和整棵左右子树所有节点进行比较。

对于 root的右子树上所有节点来说,它们的值都要比 root节点的值要大;
对于 root的左子树上所有节点来说,它们的值都要比 root节点的值要小。
对于这种情况可以使用辅助函数,增加函数参数列表,在参数中携带额外信息。

isValidBST(TreeNoderoot,TreeNodemin,TreeNodemax):相当于给子树上的所有节点添加了一个 minmin 和 maxmax 的边界,约束 rootroot 的左子树节点值不超过 root的值,右子树节点值不小于 root的值,符合了 BST的定义。

104 二叉树的最大深度https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/

  1. 边界:root == null返回0
  2. 否则返回max(左孩子的最大深度, 右孩子最大深度) + 1

111 二叉树的最小深度https://leetcode-cn.com/problems/minimum-depth-of-binary-tree/

  1. 边界1:root == null 返回0
  2. 边界1:root 的左右孩子都为null 返回1
  3. root 的左右孩子一个为null,返回另一个的mindepth
  4. root 的左右孩子都不为null,返回min(左孩子的mindepth, 右孩子的mindepth)

22 括号生成
划分子问题标准:第一个子问题,作为不可分割的整体
分段方法(a)b
(a):k对括号,子问题a是k-1对括号
b: n-k对括号
不同的k之间:加法原理
左右两个子问题:乘法原理

你可能感兴趣的:(数据结构与算法,算法,数据结构,c++)