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

第十七天| 第六章 二叉树part04 110.平衡二叉树 257. 二叉树的所有路径 404.左叶子之和

一、110.平衡二叉树

  • 题目链接:https://leetcode.cn/problems/balanced-binary-tree/

  • 题目介绍:

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

      本题中,一棵高度平衡二叉树定义为:

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gEhmaOkY-1692948217787)(E:.STU\【JAVA】\LeetCode\第17天\平衡二叉树示例.png)]

  • 思路:
    • 获取高度:
        1. 明确使用后序遍历计算高度
        2. 递归结束的条件(遇到null,返回0)
        3. 每一层的逻辑是:如果左右子树的高度差大于1,就返回-1;如果左右子树的高度差小于等于1,就返回当前节点的高度;
    • 最终判断根节点的高度,如果不等于-1,说明每一个节点都满足平衡二叉树高度差小于1的条件;如果等于-1,说明至少有一个节点不满足。
  • 代码:
class Solution {
    public boolean isBalanced(TreeNode root) {
        // 如果不等于-1,说明每一个节点都满足平衡二叉树高度差小于1的条件;如果等于-1,说明至少有一个节点不满足。
        return getHigh(root) != -1;
    }

    public int getHigh(TreeNode root){
        // 1. 明确使用后序遍历计算高度
        // 2. 递归结束的条件
        if (root == null) {
            return 0;
        }
        // 3. 每一层的逻辑是:
        //  3.1 如果左右子树的高度差大于1,就返回-1
        int leftHigh = getHigh(root.left);
        int rightHigh = getHigh(root.right);
        if (Math.abs(leftHigh - rightHigh) > 1) {
            return -1;
        }
        //  3.2 如果左右子树的高度差小于等于1,就返回当前节点的高度;
        return Math.max(leftHigh, rightHigh) + 1;
    }
}

二、257. 二叉树的所有路径

  • 题目链接:https://leetcode.cn/problems/binary-tree-paths/

  • 题目介绍:

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

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

    • 示例 1:

      输入:root = [1,2,3,null,5]
      输出:["1->2->5","1->3"]
      
  • 思路:

    • 因为要从根节点开始记录路径,所以一定是前序遍历
    • 使用一个paths列表记录每一条路径,并且在找到叶子节点之后,进行回溯
      • 这里要进行的回溯操作如下图所示:
      • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q45LLQYk-1692948217787)(二叉树的所有路径.png)]
    • 每次找到叶子节点后,将当前的路径拷贝到result中。
  • 代码:

class Solution {
    public List<String> binaryTreePaths(TreeNode root) {
        // 搞一个result,把paths里的路径拷贝成;eetCode要求输出的样式
        List<String> result = new ArrayList<>();
        if (root == null) {
            return result;
        }
        // 搞一个paths放每条路的路径
        List<Integer> paths = new ArrayList<>();
        traversal(root, paths, result);
        return result;
    }

    public void traversal(TreeNode root, List<Integer> paths, List<String> result){
        // 中:考虑到最终叶子节点也要放入paths中,所以先”中“
        paths.add(root.val);
        // 递归结束的条件,如果遇到叶子节点(左子节点和右子节点皆空),就return
        // return之前把paths中的路径拷贝进result中
        if (root.left == null && root.right == null) {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < paths.size() - 1; i++) {
                sb.append(paths.get(i)).append("->");
            }
            sb.append(paths.get(paths.size() - 1));
            result.add(sb.toString());
            return;
        }
        // 如果左子节点不空
        if (root.left != null) {
            // 遍历左子节点
            traversal(root.left, paths, result);
            // 遍历完左子节点,要回溯,因为要找到当前节点的父节点,重新开始另一条新的路径
            paths.remove(paths.size() - 1);
        }
        if (root.right != null) {
            traversal(root.right, paths, result);
            // 这里同理
            paths.remove(paths.size() - 1);
        }   
    }
}

三、404.左叶子之和

  • 题目链接:https://leetcode.cn/problems/sum-of-left-leaves/

  • 题目介绍:给定二叉树的根节点 root ,返回所有左叶子之和。

  • 思路:

    • 判断什么是左叶子节点?
    • 遍历到父节点,判断付姐带你的左孩子不为空,且左孩子的左右孩子皆为空
    • 核心判断:
      • 递归:
      • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B4lcr50x-1692948217788)(左子节点递归核心代码.png)]
      • 迭代:
      • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dbhqFLrQ-1692948217788)(左子节点迭代核心代码.png)]
  • 代码:

(1)递归

class Solution {
    public int sumOfLeftLeaves(TreeNode root) {
        if (root == null) {
            return 0;
        }
        if (root.left == null && root.right == null) {
            return 0;
        }
        int leftSum = sumOfLeftLeaves(root.left); // 左
        int rightSum = sumOfLeftLeaves(root.right); // 右
        int midValue = 0;
        if (root.left != null && root.left.left == null && root.left.right == null) {
            midValue = root.left.val;
        }
        int sum = midValue + leftSum + rightSum; // 中
        return sum;
    }
}

(2)迭代(层序遍历)

class Solution {
    public int sumOfLeftLeaves(TreeNode root) {
        int sum = 0;
        Deque<TreeNode> queue = new LinkedList<>();
        if (root != null) {
            queue.offer(root);
        }
        while (!queue.isEmpty()) {
            int size = queue.size();
            while (size-- > 0) {
                TreeNode tempNode = queue.poll();
                if (tempNode.left != null && tempNode.left.left == null && tempNode.left.right == null) {
                    sum += tempNode.left.val;
                }
                if (tempNode.left != null) {
                    queue.offer(tempNode.left);
                }
                if (tempNode.right != null) {
                    queue.offer(tempNode.right);
                }
            }
        }
        return sum;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
首先,我们需要了解什么是扩展二叉树。扩展二叉树是一种二叉树的表示方法,其中每个非叶子节点都有两个子节点,但其中一个或两个子节点可以为空。因此,扩展二叉树的前序序列可以被表示为一个字符串,其中空节点用字符“#”表示。例如,扩展二叉树“1(2(4(#)(#))(5(#)(#)))”可以表示为前序序列“124##5##”。 现在我们来考虑如何构建二叉树。我们可以使用递归的方法来构建二叉树,每次递归都处理当前节点的子树和右子树。具体来说,我们可以先读取前序序列中的下一个字符,如果当前字符是“#”,则表示该节点为空;否则,我们可以将该字符转换为数字并创建一个新节点,然后递归构建该节点的子树和右子树。 下面是 Python 代码实现: ``` python class TreeNode: def __init__(self, val=0, left=None, right=None): self.val = val self.left = left self.right = right def buildTree(preorder): def helper(): val = preorder.pop(0) if val == '#': return None node = TreeNode(int(val)) node.left = helper() node.right = helper() return node return helper() ``` 接下来,我们需要计算给定二叉树的所有叶子之和叶子是指没有右子树的子树节点。因此,我们可以使用递归的方法遍历整个二叉树,在遍历的过程中累加所有叶子节点的值。具体来说,对于每个节点,我们将其子节点的值加入结果中,然后递归处理其子树和右子树。 下面是 Python 代码实现: ``` python def sumOfLeftLeaves(root): def helper(node, is_left): if not node: return 0 if not node.left and not node.right and is_left: return node.val return helper(node.left, True) + helper(node.right, False) return helper(root, False) ``` 完整代码如下: ``` python class TreeNode: def __init__(self, val=0, left=None, right=None): self.val = val self.left = left self.right = right def buildTree(preorder): def helper(): val = preorder.pop(0) if val == '#': return None node = TreeNode(int(val)) node.left = helper() node.right = helper() return node return helper() def sumOfLeftLeaves(root): def helper(node, is_left): if not node: return 0 if not node.left and not node.right and is_left: return node.val return helper(node.left, True) + helper(node.right, False) return helper(root, False) preorder = '1(2(4(#)(#))(5(#)(#)))' root = buildTree(list(preorder)) print(sumOfLeftLeaves(root)) # 输出 4 ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值