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

day17 二叉树04

110. 平衡二叉树

用递归的话:得到左右子树的高度,判断其是否差为1,否的话,可以直接返回false了,但要怎么中断呢?——Carl用-1来表示不符合的状态,因为返回结果是自然数。很聪明,我咋没想到呢。。。这应该是大一上计导课就可以想到的小trick

临时检查:递归三要素是什么?

返回值,递归条件,终止情况?

递归函数的参数和返回值终止条件单层递归的逻辑 ——Carl

class Solution {
public:
    int flag = 0;
    // 返回值:树的高度(-1则是终止)
    // 结束条件:空节点 或 下面已经不满足平衡二叉树
    // 递归逻辑:通过左右子树的高度,判断并返回自己的高度
    int getHeight (TreeNode* root) {
        if (!root) return 0;
        int lh = getHeight(root->left), rh = getHeight(root->right);
        if (lh == -1 || rh == -1) return -1;
        if (abs(lh - rh) > 1) return -1;
        return lh > rh ? (lh + 1) : (rh + 1);
    }

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

257. 二叉树的所有路径

思路:

  1. 不知道到底有多少条路径,要回溯。

  2. 递归回溯

递归不需要返回值,终止条件是左右孩子都完成,单层递归逻辑是回溯。

从root开始加进数组,有孩子(能递归)就继续,到了叶子结点形成一条路径,然后回溯;

回溯和递归是一一对应的,有一个递归,就要有一个回溯,尽量都在一个括号处理流程里。

class Solution {
private:
    vector<string> result;
    vector<int> vec;
    void print() {
        string sPath;
        sPath += to_string(vec[0]);
        for (int i = 1; i < vec.size(); i++) {
            sPath = sPath + "->" + to_string(vec[i]);
        }
        result.push_back(sPath);
    }
    void reverse(TreeNode* root) {
        if (!root) return;
        vec.push_back(root->val);
        if (!root->left && !root->right) {
            print();
        }
        reverse(root->left);
        reverse(root->right);
        vec.pop_back();
    }

public:
    vector<string> binaryTreePaths(TreeNode* root) {
        reverse(root);
        return result;
    }
};

404. 左叶子之和

首先明确左叶子定义,是叶子结点 && 父节点的左孩子,

用递归试试:

​ 返回值,不用返回,sum全局 / 也可以返回当前节点的所有左叶子之和,参数是结点;

​ 递归终止条件:叶子结点;

​ 单层递归逻辑:有没有左孩子,并是不是左叶子,有没有右孩子

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

顺便尝试了一下vscode写力扣,还行。

今日小结

做力扣解具体问题也视为一项业务,对业务的理解也很重要;

递归真的很省心,几天没用迭代,估计又忘了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值