day17|LeetCode:● 110.平衡二叉树 ● 257. 二叉树的所有路径 ● 404.左叶子之和

本文概述了如何利用递归法解决平衡二叉树的判断、二叉树路径的寻找以及左叶子节点和的计算,通过实例深入解析递归的三个关键步骤:返回类型、终止条件和递归逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:110. 平衡二叉树

思路

题目意思就是如果左子树和右子树的高度相差大于1就不是平衡二叉树,当是平衡二叉树就返回二叉树的高度,不是就返回-1,求高度一般用后序法

递归法(后序)

class Solution {
public:
    int traversal(TreeNode* root) {
       if (root == nullptr) return 0;
       int lefthigth = traversal(root->left);
       if (lefthigth == -1)  return -1;
       int righthigth = traversal(root->right);
       if (righthigth == -1) return -1;
       if (abs(lefthigth - righthigth) > 1) return -1;
       else return max(lefthigth, righthigth) + 1;                                                                      
    }
    bool isBalanced(TreeNode* root) {
        return  traversal(root) == -1? false : true;
    }
};

递归三部曲

确定返回类型和参数类型:函数返回类型为int,代表高度或-1,参数类型为每个根

确定终止条件,就是可以确定结果的那一层,当遍历到叶子结点的下一层结点时,它们的高度为0

确定单层递归的逻辑:先得到左子树高度再得到右子树的高度,如果两边高度不符合条件则返回-1,符合条件则返回高度

值得注意的是返回后到达的是上一层的那个递归函数,如果这一层都返回-1了,那整棵棵树都是-1,所以直接在函数下面判断,如果下面一层都为-1了,后面全部返回-1了。

关键:终止条件后回到上一层递归函数的下一行


题目链接:257. 二叉树的所有路径

思路

求每二叉树的所有路径。第一个加入的就是根节点,而且自上向下加入,所以用前序遍历,因为加入的东西不能重复每条路径,不是遍历,所以需要弹出加入的点,用回溯

递归法(前序+回溯)

class Solution {
public:
    void backtracking(TreeNode* root, vector<int>& path, vector<string>& result) {
        path.push_back(root->val);
        if (root->right == nullptr && root->left == nullptr) {
                     string sPath;
            for (int i = 0; i < path.size() - 1; i++) {
                sPath += to_string(path[i]);
                sPath += "->";
            }
            sPath += to_string(path[path.size() - 1]);
            result.push_back(sPath);
            return;
        }
        if(root->left){
            backtracking(root->left, path, result);
            path.pop_back();
        }
        if(root->right){
            backtracking(root->right,path,result);
            path.pop_back();
        }
    }
    vector<string> binaryTreePaths(TreeNode* root){
     vector<string>result;
     vector<int>path;
     backtracking(root, path, result);
    return result;
    }
};

递归三部曲

确定返回类型和参数:返回类型为return,传入的参数为结果寄存数组和根结点

确定终止条件:当到达根结点时说明一条路径存储完毕,然后return,计入到参数结果数组中

确定单层递归的逻辑:每次到一个新结点都加入到一条结果集中,后面开始向左遍历当左边不为空时,向右遍历当右结点部位空时

问题

 为什么要设置左右不为空呢?

因为遍历到2时还不是叶子结点,不是一个完整路径,为空就会去遍历右结点,知道遍历到叶子结点return,返回pop()

回溯的作用,其实就是返回上一层原本的情况,值什么都一样没改变

 (二叉树)递归三原则--记住:做题不要想这个,要抽象

1.明白只有遍历完那颗树所有的分支才会真正不遍历那颗节点了(二叉树遍历完左右子树才算完结)

2.明白前中后序遍历需要遍历完哪些分支才会输出

3.明白返回上一层的return结果是交给那个递归函数的,下一层遍历就会从递归函数的下一行开始执行,且这一行一般是回溯的过程


题目链接:404. 左叶子之和

递归法(后序)

class Solution {
public:
    int sumOfLeftLeaves(TreeNode* root) {
        if (root == nullptr) return 0;
        if (root->left == nullptr && root->right == nullptr) return 0;

        int a = sumOfLeftLeaves(root->left);
        if (root->left&&!root->left->left&&!root->left->right) {
            a = root->left->val;
        }
        int b = sumOfLeftLeaves(root->right);
        return a+b;

    }
};

递归三部曲

确定返回类型和参数类型:返回类型是int,为左叶子之和,参数为根

确定终止条件:当遍历到最后叶子的下一个时因为没有左叶子可以确定结果,return0,但是叶子结点也可以确定结果也一样可以return0

确定单层递归的逻辑,算出左子树和右子树左叶子之和相加就是左叶子之和了,一般这个都是看根节点的逻辑的,看子节点的逻辑对这道题有更深刻的理解,代表左节点的数+右结点的数,一开始都为返回0,所以我们必须左叶子赋值。所以看最后三层是可以深刻理解的

如:倒数第一层左叶子返回0,右叶子也返回0,不可能让倒数第三层也返回0,所以需要加值。

更高明的方法,因为每个结点都只会遍历一次,所以判断这个点有没有左叶子,有左叶子就加入到sum中,最后返回就行了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值