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

文章介绍了LeetCode中的三个问题:110.平衡二叉树(检查二叉树是否高度平衡),257.二叉树的所有路径(生成所有从根到叶子节点的路径),以及404.左叶子之和(计算左叶子节点的和)。讲解了各自题目的描述、思路和示例代码。
摘要由CSDN通过智能技术生成

LeetCode 110.平衡二叉树

题目链接:110.平衡二叉树
文章讲解:代码随想录#110.平衡二叉树
视频讲解:后序遍历求高度,高度判断是否平衡 | LeetCode:110.平衡二叉树

题目描述

给定一个二叉树,判断它是否是高度平衡的二叉树。
本题中,一棵高度平衡二叉树定义为:

一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。

示例1
在这里插入图片描述

输入:root = [3,9,20,null,null,15,7]
输出:true

示例2

输入:root = [1,2,2,3,3,null,null,4,4]
输出:false

示例3

输入:root = []
输出:true

提示

  • 树中的节点数在范围 [0, 5000] 内
  • -10^4 <= Node.val <= 10^4

思路

这道题的关键是每个节点 的左右两个子树的高度差的绝对值不超过1。
可以通过后序遍历来计算每个节点的左右子树的高度(该节点到叶子节点),如果超过1说明不是平衡二叉树。
具体思路可以看代码随想录。

参考代码

int getHeight(struct TreeNode *node)
{
    if (node == NULL)
        return 0; // 当遇到空节点时终止,返回0
    
    int lcnt = getHeight(node->left); // 处理左子树
    if (lcnt == -1) // 如果左子树不是平衡二叉树,则直接返回-1
        return -1;
    int rcnt = getHeight(node->right); // 处理右子树
    if (rcnt == -1) // 如果右子树不是平衡二叉树,则直接返回-1
        return -1; 
    
    if (abs(lcnt - rcnt) > 1) { // 处理中节点
    	// 如果左右节点高度超过1,说明以中节点为根节点的二叉树不是平衡二叉树
        return -1; 
    }
    int depth = lcnt > rcnt ? lcnt : rcnt;
    return 1 + depth;

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

LeetCode 257. 二叉树的所有路径

题目链接:257. 二叉树的所有路径
文章讲解:代码随想录#257. 二叉树的所有路径
视频讲解:递归中带着回溯,你感受到了没?| LeetCode:257. 二叉树的所有路径

题目描述

给你一个二叉树的根节点 root ,按 任意顺序 ,返回所有从根节点到叶子节点的路径。

叶子节点 是指没有子节点的节点。

示例1
在这里插入图片描述

输入:root = [1,2,3,null,5]
输出:[“1->2->5”,“1->3”]

示例2

输入:root = [1]
输出:[“1”]

提示

  • 树中节点的数目在范围 [1, 100] 内
  • -100 <= Node.val <= 100

思路

本题需要使用递归结合回溯对节点进行前序遍历。

参考代码

int cnt;
typedef struct {
    int index;
    int num[100];
}Stack;

void traversal(struct TreeNode *node, Stack *stack, char **res)
{
    stack->num[stack->index] = node->val; // 将中节点的数值添加到stack中
    if (node->left == NULL && node->right == NULL) { // 当遍历到叶子节点时输出
        int len = 0;
        char ch[10000] = {0};
        for (int i = 0; i <= stack->index; i++) {
            char s[5] = {0};
            sprintf(s, "%d", stack->num[i]);
            len += strlen(s);            
            strcat(ch, s);
            if (i < stack->index) {
                len += 2;
                strcat(ch, "->"); 
            }
        }
        ch[len++] = '\0';
        res[cnt] = (char*)malloc(len * sizeof(char));
        strcpy(res[cnt++], ch);
        return;
    }

    if (node->left) { // 处理左节点
        stack->index++;
        traversal(node->left, stack, res);
        stack->index--; // 回溯
    }
    if (node->right) { // 处理右节点
        stack->index++;
        traversal(node->right, stack, res);
        stack->index--; // 回溯
    }
}

char** binaryTreePaths(struct TreeNode* root, int* returnSize) {
    if (root == NULL) return NULL;
    cnt = 0;
    char **res = (char **)malloc(100*sizeof(char*));
    Stack stack = {0};
    traversal(root, &stack, res);
    *returnSize = cnt;
    return res;
}

LeetCode 404.左叶子之和

题目链接:404.左叶子之和
文章讲解:代码随想录#404.左叶子之和数
视频讲解:二叉树的题目中,总有一些规则让你找不到北 | LeetCode:404.左叶子之和

题目描述

给定二叉树的根节点 root ,返回所有左叶子之和。

示例1
在这里插入图片描述

输入:root = [3,9,20,null,null,15,7]
输出:24
解释: 在这个二叉树中,有两个左叶子,分别是 9 和 15,所以返回 24

示例2

输入:root = [1]
输出:0

提示

  • 节点数在 [1, 1000] 范围内
  • -1000 <= Node.val <= 1000

思路

如何确定一个节点是左叶子?
如果一个节点的左孩子节点不为空,并且左孩子节点它的左右孩子节点都为空,则这个节点的左孩子节点为左叶子节点。
也就是说,无法判断当前节点是不是左叶子,需要通过该节点的父节点来判断其父节点的左孩子是不是左叶子节点。

参考代码

int sumOfLeftLeaves(struct TreeNode* root){
    if (root == NULL) return 0;
    int val = 0;
    if (root->left != NULL && root->left->left == NULL && root->left->right == NULL) {
        val = root->left->val; // 找到左叶子节点
    }
    return val + sumOfLeftLeaves(root->left) + sumOfLeftLeaves(root->right);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值