【代码随想录算法训练Day17】LeetCode 110. 平衡二叉树、LeetCode 257.二叉树的所有路径、LeetCode 404.左叶子之和

Day17 二叉树第四天

LeetCode 110. 平衡二叉树【后序遍历】

平衡二叉树仍是后序遍历,就是获取左右子树的高度然后作差,如果子树就不平衡,那么就直接将-1向上传给父节点,否则该数的高度为左右子树高度的最大值+1。

class Solution {
public:
    int getHeight(TreeNode* node){
        if(!node) return 0;
        int leftHeight=getHeight(node->left);
        if(leftHeight==-1) return -1;
        int rightHeight=getHeight(node->right);
        if(rightHeight==-1) return -1;
        if(abs(rightHeight-leftHeight)>1) return -1;
        else return 1+max(rightHeight,leftHeight);
    }

    bool isBalanced(TreeNode* root) {
        return getHeight(root)==-1?false:true;
    }
};

LeetCode 257.二叉树的所有路径 【前序遍历】

首次遇到回溯过程,我们在遍历完之后要将元素弹出,这样才能保证遍历往回走时节点也弹出了。
本题有几点需要注意:
1.递归推出的条件是节点左右节点均为空,而不是节点为空。
2.前序遍历时【中】的过程,也就是记录节点的过程要写在递归结束判断之前,否则会遗落叶子结点。
3.注意回溯的过程。

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

    vector<string> binaryTreePaths(TreeNode* root) {
        if(!root) return res;
        travesal(root,path,res);
        return res;
    }
};

LeetCode 404.左叶子之和【后序遍历】

本题的难点在于处理这个节点时,我们只能知道他是叶子,无法确定是否是左叶子,所以我们必须在处理他的父节点时处理这个节点,也就是如果一个节点的左孩子不为空,且这个左孩子是叶子节点,就把他的数值加到这棵树的左叶子之和中,最后这棵树的左叶子之和就是左右孩子的左叶子之和的和。
也就是说如果我们处理到了叶子节点,那么直接返回0即可,不必再向下递归一层。因为我们已经在叶子结点的上一层获取到了左叶子的和。这样可以减少递归次数,使代码效率更高。

class Solution {
public:
    int sumOfLeftLeaves(TreeNode* root) {
        if(!root) return 0;
        if(!root->left && !root->right) return 0;
        int leftSum=sumOfLeftLeaves(root->left);
        if(root->left && !root->left->left && !root->left->right)
            leftSum=root->left->val;
        int rightSum=sumOfLeftLeaves(root->right);
        int sum=leftSum+rightSum;

        return sum;
    }
};

在写树和递归的过程中,要多注意题目的细节。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值