110.平衡二叉树 257. 二叉树的所有路径 404.左叶子之和

文章介绍了如何使用递归方法解决三个二叉树相关问题:判断平衡二叉树、找出所有从根到叶子的路径以及计算左叶子之和。通过后序遍历和前序遍历策略,展示了如何在递归过程中处理平衡性检查和路径记录。
摘要由CSDN通过智能技术生成

110.平衡二叉树 257. 二叉树的所有路径 404.左叶子之和

110.平衡二叉树 (优先掌握递归)

力扣题目链接(opens new window)

给定一个二叉树,判断它是否是高度平衡的二叉树。

本题中,一棵高度平衡二叉树定义为:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。

示例 1:

给定二叉树 [3,9,20,null,null,15,7]

110.平衡二叉树

返回 true 。

示例 2:

给定二叉树 [1,2,2,3,3,null,null,4,4]

110.平衡二叉树1

返回 false 。

思路

递归法 后序遍历
使用递归方法求出左右子树的深度,并求出左右子树的差,这个流程为后序遍历
题目要求一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。如果超过 1,则该树不是平衡二叉树
所以需要对左右子树的差进行判断,超过一则不符合条件

代码如下

// 时间复杂度o(n)
// 空间复杂度o(n) 
public static boolean isBalanced(TreeNode root) {
    if (root == null)
        return true;

    int result = isTree(root);
    if(result == -1)
        return false;
    return true;
}

public static int isTree(TreeNode node) {
    if (node == null)
        return 0;

    int leftDepth = isTree(node.left);
    if(leftDepth == -1)
        return -1;
    int rightDepth = isTree(node.right);
    if(rightDepth == -1)
        return -1;
    int cha = Math.abs(leftDepth - rightDepth);
    if (cha > 1) {
        return -1;
    }
    return Math.max(leftDepth, rightDepth) + 1;
}

问题

我开始的写法,想在递归方法中使用boolean isBalance作为判断平衡二叉树的条件
调用递归算法结束后,判断isBalance的值即可。
但是在调试中发现,isBalance的值没有改动过。
错误代码:猜测时布尔类型引用传递的问题

public static boolean isBalanced(TreeNode root) {
    if (root == null)
        return true;
    boolean isBalance = true;
    isTree(root, isBalance);
    return isBalance;
}

public static int isTree(TreeNode node, boolean isBalance) {
    if (node == null)
        return 0;
    int leftDepth = isTree(node.left, isBalance);
    int rightDepth = isTree(node.right, isBalance);
    int cha = Math.abs(leftDepth - rightDepth);
    if (cha > 1) {
        isBalance = false;
    }
    return Math.max(leftDepth, rightDepth) + 1;
}

257. 二叉树的所有路径 (优先掌握递归)

力扣题目链接(opens new window)

给定一个二叉树,返回所有从根节点到叶子节点的路径。

说明: 叶子节点是指没有子节点的节点。

示例: 257.二叉树的所有路径1

思路

递归法 前序遍历
题目要求根节点到所有叶子结点的路径,那么我们需要先访问根节点,然后一层层向下访问直至叶子结点,那么前序遍历符合先访问根节点的条件
这道题目需要用到回溯回退路径,来进入下一个路径,那么在遍历结束后,去除路径的最后一个结点
回溯和递归是息息相关的,有一个递归就要有一个回溯
递归法三要素
方法的入参和返回值 : TreeNode node List String result List String path
方法的中止条件: 到叶子结点中止,记录路径
核心逻辑:前序遍历,有一个递归就要有一个回溯

代码如下

// 时间复杂度o(n)
// 空间复杂度o(n) 
public List<String> binaryTreePaths(TreeNode root) {
    List<String> result = new ArrayList<>();
    List<String> path = new ArrayList<>();
    if (root == null)
        return result;
    preOrder(root, result, path);
    return result;
}

public void preOrder(TreeNode node, List<String> result, List<String> path) {


    path.add(String.valueOf(node.val));

    if (node.left == null && node.right == null) {// 终止条件  找到叶子节点
        String str = "";
        for (int i = 0; i < path.size(); i++) {
            if (i == path.size() - 1) {
                str = str + path.get(i);
            } else {
                str = str + path.get(i) + "->";
            }
        }
        result.add(str);
        return;
    }

    if (node.left != null) {
        preOrder(node.left, result, path);
        path.remove(path.size() - 1);
    }
    if (node.right != null) {
        preOrder(node.right, result, path);
        path.remove(path.size() - 1);
    }

}

404.左叶子之和 (优先掌握递归)

力扣题目链接(opens new window)

计算给定二叉树的所有左叶子之和。

示例:

404.左叶子之和1

思路

递归法
后序遍历 计算左右子树中的所有左叶子结点的值,并返回
那么怎么判断当前的叶子结点是左叶子结点呢?
这里定义一个常量sum.
sum = 0表示该节点是由父节点的左结点,sum = 1表示该节点是父结点的右节点
在递归遍历左节点时,将sum = 0作为入参。 遍历右节点,将sum = 1作为入参。用于表示当前结点是左右结点
接下来在中止条件中加以判断,如果sum = 0,当前叶子结点为左节点,返回当前叶子结点的值
否则为当前叶子结点为右节点,返回0

代码如下

// 时间复杂度o(n)
// 空间复杂度o(n) 
public int sumOfLeftLeaves(TreeNode root) {
    if(root == null)
        return 0;
    return preOrder(root,0);
}

public int preOrder(TreeNode node, int sum) {
    if (node.left == null && node.right == null && sum == 0) {
        return node.val;
    }
    if (node.left == null && node.right == null && sum == 1) {
        return 0;
    }


    int result = 0;
    if (node.left != null) {
        int leftValue = preOrder(node.left, 0);
        result = result + leftValue;
    }
    if (node.right != null) {
        int rightValue = preOrder(node.right, 1);
        result = result + rightValue;
    }
    return result;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值