二叉树与递归
LeetCode 104. 二叉树的最大深度 原题链接
根节点到最远叶子节点最长路径上的节点数。
不要一上来就陷入二叉树的细节,将题目中给的具体的二叉树结构转换成一般的二叉树的结构进行分析,三角形表示子树。
整棵树的最大深度 = max(左子树的最大深度,右子树的最大深度) + 1。
原问题:计算整棵树的最大深度。
子问题:计算左/右子树的最大深度。
计算左子树最大深度和右子树的最大深度与计算整棵树的最大深度是相似的。
类比循环,循环就是在重复执行同样一份代码,计算子问题和原问题也应用一份代码来计算。
注意与循环是有区别的,例如,写一个循环去计算数组的元素和。做法为遍历数组中的每个数将值加到一个循环外的变量,每次循环加的都是同一个循环外的变量。
然而这个问题是有嵌套关系的,需要将计算结果返回给它的上一级问题,而它的上一级问题又会将计算结果返回给上上一级问题,依次类推,所以使用递归实现更合适。
从原问题出发,不断将问题分解成规模更小的子问题,这个过程是递。
不断递下去,总会有个尽头,这个尽头就是递归的边界条件。此问题中边界条件就是空节点,直接返回 0 作为答案,返回的过程就是归。
这样,边界条件和非边界条件都弄清楚了。
最简单和常见的数学归纳法是证明当n
等于任意一个自然数时某命题成立。证明分下面两步:
1
因其作为自然数集合中中最小值)n=m+1
时命题成立。(m代表任意自然数)”这种方法的原理在于:首先证明在某个起点值时命题成立,然后证明从一个值到下一个值的过程有效。当这两点都已经证明,那么任意值都可以通过反复使用这个方法推导出来。把这个方法想成多米诺骨牌效应也许更容易理解一些。2lB]例如:你有一列很长的直立着的多米诺骨牌,如果你可以:
则可下结论:所有的骨牌都会倒下。
class Solution {
public:int maxDepth(TreeNode* root) {if (root == NULL) return 0;int l_depth = maxDepth(root->left);int r_depth = maxDepth(root->right);return max(l_depth, r_depth) + 1;}
};
时间复杂度为 O(n)O(n)O(n),尾音每个节点都会遍历了一次。
在递归的时候除了将节点传下去,还可以将路径上的节点个数传下去,根节点个数为1
。
在递归的同时可以维护一个全局变量,每次+1
之后都更新这个全局变量的最大值。
遍历完整棵树,这个全局变量就是答案。
class Solution {
public:int ans = 0;void dfs(TreeNode* root, int cnt) {if (root == NULL) return;cnt += 1;dfs(root->left, cnt);dfs(root->right, cnt);ans = max(ans, cnt);}int maxDepth(TreeNode* root) {dfs(root, 0);return ans;}
};