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

在这里插入图片描述
递归法,考虑当我站在一个节点上时,我应该干点啥,是不是想知道是否是平衡二叉树,就得知道左右子树的高度,进一步判断这个节点下是不是平衡的,天然的就是一个后序遍历的场景,从左右子树收集信息

/**
 * 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:
    bool res = true;
    int traceback(TreeNode * node){
          if(node == NULL){
            return 0;
          }

        int leftHigh =   traceback(node->left);
        int rightHigh =  traceback(node->right);

        if(abs(leftHigh - rightHigh) > 1){
           res = false;
        }
        return max(leftHigh,rightHigh) + 1;
    }
    bool isBalanced(TreeNode* root) {
        traceback(root);
        return res;
    }
};

如果想改成迭代法,就可以使用栈的数据结构,来调整各个节点的次序,后序遍历的迭代法大框架下改改就行

在这里插入图片描述
在这里插入图片描述
同样的,递归时同样是看:当我站在一个节点上时,我该干啥,是不是直接把现在的值记录一下就行,后面有没有节点,子树长啥样,管不着(这个时候是不是感觉有点先序遍历的意思)

/**
 * 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:
    vector<string> paths;
    void traceback(TreeNode * node,string path){
        if(node == NULL){
            return;
        }
        path += to_string(node->val);
        path += "->";
        if(node->left == NULL && node->right == NULL){
             path.pop_back();
             path.pop_back();
             paths.push_back(path);
        }
        traceback(node->left,path);
        traceback(node->right,path);
    }
    vector<string> binaryTreePaths(TreeNode* root) {
        traceback(root,"");
        return paths;
    }
};

迭代法就是在先序遍历迭代法的大框架下改改,需要注意的是,每次是遇到了一个确切的叶子节点才是记录路径的时机

在这里插入图片描述
在这里插入图片描述
继续考虑这个问题,当我站在一个节点上时,我该干啥,要返回左叶子的和,是不是现在要有当前节点的左子树的左叶子和,以及右子树的左叶子和,还有当前节点的左叶子和那么后序遍历次序定下来了

递归的话先确定一下形参和返回值,形参(就根节点一个自变量),返回值(当然是当前节点的左叶子和咯),次序为后序遍历

/**
 * 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 traceback(TreeNode * node){
         if(node == NULL){
            return 0;
         }
         int levesSum = 0;

         int levesSumL = traceback(node->left);
         int levesSumR = traceback(node->right);

         levesSum = levesSumL + levesSumR;
         if(node->left && node->left->left == NULL && node->left->right == NULL){
             levesSum += node->left->val;
         }
         return levesSum;

    }
    int sumOfLeftLeaves(TreeNode* root) {
         return traceback(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 sumOfLeftLeaves(TreeNode* root) {
        int res = 0;
        queue<TreeNode *> q;

        if(root == NULL){
          return res;
        }
        q.push(root);

        while(!q.empty()){
            int size = q.size();

            while(size--){
                TreeNode * node = q.front();
                q.pop();
                if(node->left){
                    q.push(node->left);
                    if(node->left->left == NULL && node->left->right == NULL){
                           res += node->left->val;
                    }
                }
                if(node->right){
                   q.push(node->right);
                }
            }

        }
        return res;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值