算法训练营DAY17|110.平衡二叉树、257. 二叉树的所有路径、404.左叶子之和

110. 平衡二叉树 - 力扣(LeetCode)https://leetcode.cn/problems/balanced-binary-tree/题目大意是判断一个二叉树是否是平衡二叉树,那么什么是平衡二叉树呢?该树的每一个节点的两棵子树高度差的绝对值不高于1,则说明该二叉树是平衡二叉树。思路是这样的:我们可以写一个函数,它的作用是帮我们算出两子树最高的那一个是多高,直到返回到根节点,在比较各个子树的高矮时,如果碰到两子树相差过高,则直接返回-1,在下面比较时我们直接能判断出来。函数的书写我们使用后序遍历的思路来书写,因为我们要判断一个节点的子树,相差是否大于1,然后向上返回,只有后序遍历才能先遍历到两子树。

class Solution {
public:
int getheight(TreeNode*root){
    if(root==NULL)return 0;
    int leftheight=getheight(root->left);
    if(leftheight==-1)return -1;
    int rightheight=getheight(root->right);
    if(rightheight==-1)return -1;
    return abs(leftheight-rightheight)>1?-1:1+max(leftheight,rightheight);
}
    bool isBalanced(TreeNode* root) {
        return getheight(root)==-1?false:true;
    }
};

如图所示,递归的思路就是遍历到空节点就是左右子树为0,所以返回0,然后创建两个整形来保存数据,进入递归分别保存左右子树的高度,然后在最后处理中间节点时作比较,如果高度大于1返回-1,到上一层if判断如果为-1,直接返回-1跳出,如果不是继续遍历,接着将结果赋给整型变量存储。

我们是使用判断子树高度的思想来间接判断各子树是否能够平衡,没有写过该题的我认为该思路并不好直接想到。


257. 二叉树的所有路径 - 力扣(LeetCode)https://leetcode.cn/problems/binary-tree-paths/这道题就是遍历二叉树的所有节点然后将他们用->连接起来,每一条不同的路径使用不同的字符串,而不是所有路径都是一个字符串。

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

这里我们采用前序遍历来写函数的具体实现,要将加入节点写到最前面,因为我们的递归终止条件是遇到叶子节点时,跳出递归返回。需要注意的是每次写完递归之后,还要再下面写下pop,原因是在进入下一个不同路径之前,我们需要pop函数帮助我们弹出这条路径的节点,才能让数组加入下一条路径的数据,而将该数组转化为字符串形式和添加->等这些操作都在,递归的终止条件下进行。


404. 左叶子之和 - 力扣(LeetCode)https://leetcode.cn/problems/sum-of-left-leaves/这道题很简单,就是求出该树中左叶子的节点值和就可以了,左叶子是左子树和右子树的全部左子叶这是需要注意的点。解题思路是:写一个函数,分别遍历各节点的左子叶是不是叶子节点,如果是则加入进总数中,最后返回总数。这里我们判断的是左子叶的上一个节点,而不是等到判断到左子叶节点在做处理,这里我们仍然使用后序遍历的方法,将各节点左子叶的总数依次返回直到根节点为止。

class Solution {
public:
    int sumOfLeftLeaves(TreeNode* root) {
        if(root==NULL)return 0;
        int left=sumOfLeftLeaves(root->left);
        if(root->left!=NULL&&root->left->left==NULL&&root->left->right==NULL)
        left= root->left->val;//不要直接写成return把所有情况都遍历完再返回
        int right=sumOfLeftLeaves(root->right);
        int sum=left+right;
        return sum;
    }
};

我们在遍历右侧子树时,也就是后序遍历中的右半部分,只管向里递归而不做判断的处理,因为要算得是左叶字节点的值,当它一直递归下去往上返回后还是交给左边递归来进行节点的判断。 


以上代码均可ac。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学习算法的杨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值