递归recursion(实现形式)
函数自身调用自身
通过函数体来进行循环
以相似的方法重复进行的过程
例子:
def factorial(n):
# 要注意边界
if n <= 1:
return 1
return n * factorial(n - 1)
![截屏2021-06-26 下午8.09.01](https://tva1.sinaimg.cn/large/008i3skNgy1grvxdsci8gj30qk0hwq50.jpg)
![截屏2021-06-26 下午8.10.24](https://tva1.sinaimg.cn/large/008i3skNgy1grvxf5ycadj30ti0hm0vv.jpg)
递归的三个关键
- 定义需要递归的问题(重叠子问题)——数学归纳法
- 确定递归边界
- 保护与还原现场
全局变量要还原,局部变量不用
分治(算法)
把原问题划分为若干个子问题,分别解决后,再把结果合并
关键点
- 原问题和各个子问题都是重复的(同类的)————递归定义
- 除了向下递归“问题”,还要向上合并“结果”
分治算法一般用递归实现
划分子问题标准:第一个子问题,作为不可分割的整体
实战
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/
- 边界:root == null
- 左孩子等于右孩子,右孩子等于左孩子
- 翻转左节点,翻转右节点
98 验证二叉搜索树https://leetcode-cn.com/problems/validate-binary-search-tree/
- 边界:root == null返回0
- 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/
- 边界:root == null返回0
- 否则返回max(左孩子的最大深度, 右孩子最大深度) + 1
111 二叉树的最小深度https://leetcode-cn.com/problems/minimum-depth-of-binary-tree/
- 边界1:root == null 返回0
- 边界1:root 的左右孩子都为null 返回1
- root 的左右孩子一个为null,返回另一个的mindepth
- root 的左右孩子都不为null,返回min(左孩子的mindepth, 右孩子的mindepth)
22 括号生成
划分子问题标准:第一个子问题,作为不可分割的整体
分段方法(a)b
(a):k对括号,子问题a是k-1对括号
b: n-k对括号
不同的k之间:加法原理
左右两个子问题:乘法原理