二叉树与递归思路
对于二叉树问题,不要一开始就陷入细节,而是思考整棵树与其左右子树的关系
整棵树最大深度 = max(左子树最大深度,右子树最大深度)+ 1
原问题:计算整棵树的最大深度
子问题:计算左/右子树的最大深度
子问题与原问题相似
类比循环,执行的代码也应该相同,但是子问题需要把计算结果返给上一级,适合递归
递归是有嵌套关系的,和循环不同
子问题的规模总比原问题小,不断递下去,总会有尽头,我们便得到了递归的边界条件,返回答案(归)
理解的话,和数学归纳法类似
边界条件就是数学归纳法中,“当n = 1时成立”。非边界条件,就是数学归纳法第二步
简单实践一下
力扣104.二叉树的最大深度
给定一个二叉树 root ,返回其最大深度。
二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int maxDepth(TreeNode* root) {
//先得到寻找到边界条件,即找不到叶子节点了
if(root == nullptr){
return 0;
}
//计算左子树的最大深度
int l_depth = maxDepth(root->left);
//计算右子树的最大深度
int r_depth = maxDepth(root->right);
//比较左右子树的谁更深,再加上根节点
return max(l_depth, r_depth) + 1;
}
};
因为每个节点都遍历了一次,所以时间复杂度是O(n)
因为递归的时候,原节点仍然存在,这是递归的return处,所以我们递了n个节点,就用了n个节点 的空间,最先递的节点最后拿到return,这个数据结构叫“栈”。所以空间复杂度也是O(n)
另一种递归思路
除了可以把节点传下去,还可以把路径上的节点个数传下去根节点为1,根的左右节点都为2,把这个数字传下去,在传递的时候同时维护一个全局变量,每次+1后就更新全局变量的最大值,遍历完数,全局变量就是最大值。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
//维护一个全局变量
int ans = 0;
//递归的时候需要把当前的深度传递下去,所以自定义一个方法,带上层数的参数
void dfs(TreeNode* node, int depth){
if (node == nullptr) {
return;
}
depth++;
ans = max(ans, depth);
dfs(node->left, depth);
dfs(node->right, depth);
}
int maxDepth(TreeNode* root) {
//从根节点开始,根节点存在则为1,不存在则为0,所以这里是起始答案是0
dfs(root, 0);
return ans;
}
};
希望能对你有帮助!
有什么问题发在评论区大家一起讨论解决进步!
算法学习处: b站灵茶山艾府
看到递归就晕?带你理解递归的本质!_哔哩哔哩_bilibili