代码随想录算法训练营第十七天|110.平衡二叉树 、 257. 二叉树的所有路径 、 404.左叶子之和

文章介绍了如何利用后序遍历判断平衡二叉树,通过计算左右子树的高度差来确定平衡状态。同时,文章讲解了前序遍历在找到二叉树所有路径中的应用,以及如何通过后序遍历求解左叶子之和的问题,强调了遍历顺序、回溯和条件判断的重要性。

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

110.平衡二叉树

题目链接/文章讲解/视频讲解:代码随想录

1.代码展现

 //110.平衡二叉树
    int getHeight_balance(TreeNode* node) {
        //step1 确定参数
        //step2 确定中止条件
        if (node == nullptr) {
            return 0;
        }
        //step3 确定单层迭代逻辑
        //这里使用后序遍历
        //step3.1 判断左右子节点是否为平衡二叉树,不是的话返回-1
        int leftHeight = getHeight_balance(node->left);
        if (leftHeight == -1) {
            return -1;
        }
        int rightHeight = getHeight_balance(node->right);
        if (rightHeight == -1) {
            return -1;
        }
        //中,对高度进行处理
        //step3.2 非平衡二叉树的情况
        if (abs(leftHeight - rightHeight) > 1) {
            return -1;
        }
        //step3.3 正常情况下返回高度
        return 1 + max(rightHeight, leftHeight);
    }

    bool isBalanced(TreeNode* root) {
        if (getHeight_balance(root) == -1) {
            return false;
        }
        return true;
    }

 2.本题小节

        基本思路:首先要明确平衡二叉树的概念,本题的基础是求二叉树的深度,二叉树的深度十左子树和右子树中深度较大的决定的,此题判断是否为平衡二叉树,因此此题要判断的是左子树与右子树高度差不超过1。本题用得后序遍历,在处理父节点时的时候需要判断左右子树高度差,如果大于1,则返回-1;同时,处理左右节点时,如果出现了高度为-1,那么直接返回-1。

        思考:本题是在求二叉树深度的基础上进行的扩展,高度差超过一的话,就必定不为平衡二叉树,一直向上返回-1即可。

257. 二叉树的所有路径

题目链接/文章讲解/视频讲解:代码随想录

1.代码展示

  //257.二叉树的所有路径
    void travelsal(TreeNode* node, vector<int>& vnTravel, vector<string>& vsResult) {
        //step1 确定传入参数
        //step2 确定终止条件
        //由于本题是前序遍历,终止条件和后序遍历不一样
        vnTravel.push_back(node->val); //中,
        if (node->left == nullptr && node->right == nullptr) {
            //叶子节点中,遍历轨迹并储存结果
            string sTravel;
            for (int i = 0; i < vnTravel.size(); i++) {
                if (i == vnTravel.size() - 1) {
                    sTravel = sTravel + to_string(vnTravel[i]);
                }
                else {
                    sTravel = sTravel + to_string(vnTravel[i]) + "->";
                }

            }
            vsResult.push_back(sTravel);
            return;
        }
        //step3 确定单层遍历逻辑
        //中,需要写在中止条件上面,否则叶子节点数据会丢失
        //左
        if (node->left) {
            travelsal(node->left, vnTravel, vsResult);
            //回溯
            vnTravel.pop_back();
        }
        //右
        if (node->right) {
            travelsal(node->right, vnTravel, vsResult);
            //回溯
            vnTravel.pop_back();
        }
    }
    vector<string> binaryTreePaths(TreeNode* root) {
        vector<int> vnTravel;
        vector<string> vsResult;
        if (root == nullptr) {
            return vsResult;
        }
        travelsal(root, vnTravel, vsResult);
        return vsResult;
    }

 2.本题小节

        基本思路:本题使用的是前序遍历法,用得迭代和回溯解决的问题。本题之所以用前序遍历,是因为前序遍历的指向正好是从根节点指向叶子结点的,是一条路径。首先明确传入的参数,有node,收集路径点的vector容器以及储存结果的vector容器;然后是终止条件,与以前到叶子节点下的nullptr终止条件不同,本题到了叶子就终止了,因为到了这里就正好收集到了所有的路径,并且此时要将路径点取出,构建成string存入结果容器中;最后是单层迭代逻辑,首先是父节点,这里的父节点位置比较特殊,在中止条件之前,如果在终止条件后的话,会丢掉叶子节点的路径,然后是左子树节点,如过节点存在,则继续,调用迭代函数后,pop掉容器中的最后一个路径点(这是本题回溯的精华所在,画图就可以看见它的妙处),右子树节点也是一样的。

        思考:本题的妙点就在于pop的处理,画图可以知道,走到叶子节点将结果储存后,pop掉最后的路径点,再进入另外一个叶子节点,储存好路径后,再pop掉最后一个路径点,返回到父节点中再pop一次最后的结果...实在是太妙了!!

404.左叶子之和 

题目链接/文章讲解/视频讲解:代码随想录

1.代码展示

    //404.左叶子之和
    int sumOfLeftLeaves(TreeNode* root) {
        //step1 确定参数
        //step2 确定中止条件
        //本题要求只用父节点
        if (root == nullptr) {
            return 0;
        }
        if (root->left == nullptr && root->right == nullptr) {
            return 0;
        }
        //step3 单层迭代逻辑
        //后序遍历
        int numLeft = sumOfLeftLeaves(root->left);
        int numRight = sumOfLeftLeaves(root->right);
        //只在叶子结点的父节点操作
        if (root->left != nullptr && root->left->left == nullptr && root->left->right == nullptr) {
            numLeft = root->left->val;
        }
        return numLeft + numRight;
    }

 2.本题小节

        本题思路:本题使用后序遍历法,首先确定参数为node;然后确定终止条件,这里再叶子节点下或者叶子节点处中止都可以,因为主要是对叶子节点的父节点操作;然后是单层迭代函数,左右调用迭代函数,对叶子结点的父节点进行操作,获取左叶子节点的值,在中返回左右节点之和。

        思考:这一题并不是对所有的节点都进行处理的,而是选择性的对左叶子节点进行处理,因此会有一些限制条件,多思考,多画图!!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值