Day17代码随想录二叉树part04:110.平衡二叉树、257. 二叉树的所有路径、404.左叶子之和

文章介绍了如何通过递归实现平衡二叉树的高度检查,使用前序遍历获取二叉树的所有路径,并解决左叶子之和的问题。涉及Python代码示例和关键数据结构定义。
摘要由CSDN通过智能技术生成

Day17 二叉树part04

110.平衡二叉树

本题的思路:检查左右子树的高度,如果检查过程中就发现了高度差大于1的情况直接返回-1,计算高度采用后序遍历

递归逻辑:

  • 明确递归函数的参数和返回值:**参数:**当前传入节点。 返回值:以当前传入节点为根节点的树的高度。如果当前传入节点为根节点的二叉树已经不是二叉平衡树了,还返回高度的话就没有意义了。所以如果已经不是二叉平衡树了,可以返回-1 来标记已经不符合平衡树的规则了。
  • 终止条件:遇到空节点则返回高度为0
  • 明确单层递归的逻辑:如果左右子树已经得到标记高度为-1则直接返回-1,代表已经不是平衡二叉树了;如果都不是则计算一下两者的差值,对中间的根节点进行更新(伪代码)
int leftHeight = getHeight(node->left); // 左
if (leftHeight == -1) return -1;
int rightHeight = getHeight(node->right); // 右
if (rightHeight == -1) return -1;

int result;
if (abs(leftHeight - rightHeight) > 1) {  // 中
    result = -1;
} else {
    result = 1 + max(leftHeight, rightHeight); // 以当前节点为根节点的树的最大高度
}

return result;

代码python:

class Solution:
    def isBalanced(self, root: Optional[TreeNode]) -> bool:
        result = self.get_height(root)
        if result == -1: return False
        else: return True
        
    def get_height(self, root: TreeNode) ->int:
        if not root:
            return 0
        left_height = self.get_height(root.left)
        if left_height == -1: return -1
        right_height = self.get_height(root.right)
        if right_height == -1: return -1
        if abs(left_height-right_height)>1:
            return -1
        else:
            return 1+max(left_height, right_height)

257. 二叉树的所有路径

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

采用的是前序遍历:因为由父节点指向子节点生成一条路径

为什么需要回溯:因为我们要把路径记录下来,需要回溯来回退一个路径再进入另一个路径。

  • **递归参数和返回值:**当前根节点cur,当前路径path,结果路径result
  • **终止条件:**之前都是如果根节点为None的情况终止,但是本题中是想找到叶子节点返回,也就是循环到none的上一层,即判断cur→left == NULL并且cur→right == NULL的时候是叶子节点;
  • 为什么不想None终止呢,这涉及到下面单层递归的逻辑,每次都是先将目前的节点cur放到路径里,然后判断是不是叶子节点,如果最后的结果是None那么相当于多放了一个None进来
  • **单层递归逻辑:因为是前序遍历(中左右)所以先处理中的逻辑,中间节点就是我们要记录路径上的节点,先放进path中。**如果已经是叶子节点了就不继续递归了。递归完,要做回溯啊,因为path 不能一直加入节点,它还要删节点,然后才能加入新的节点
  • 回溯和递归是一一对应的:左侧是正确的,右侧为错误的
if (cur->left) {
    traversal(cur->left, path, result);
    path.pop_back(); // 回溯
}
if (cur->right) {
    traversal(cur->right, path, result);
    path.pop_back(); // 回溯
}
if (cur->left) {
    traversal(cur->left, path, result);
}
if (cur->right) {
    traversal(cur->right, path, result);
}
path.pop_back();

python代码:

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def traversal(self, cur, path, result):
        path.append(cur.val)
        if not cur.left and not cur.right:
            res_path = '->'.join(map(str, path))
            result.append(res_path)
            return
        if cur.left:
            self.traversal(cur.left, path, result)
            path.pop()
        if cur.right:
            self.traversal(cur.right, path, result)
            path.pop()

    def binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]:
        result = []
        path = []
        if not root:
            return result
        self.traversal(root, path, result)
        return result

404.左叶子之和

首先要注意是判断左叶子,不是二叉树左侧节点,所以不要上来想着层序遍历。

因为题目中其实没有说清楚左叶子究竟是什么节点,那么我来给出左叶子的明确定义:节点A的左孩子不为空,且左孩子的左右孩子都为空(说明是叶子节点),那么A节点的左孩子为左叶子节点

思路:

  • 后序遍历:逐层向上每个子树的左叶子之和
  • 判断的时候是cur→left不为空且cur→left的left和right为空
class Solution:
    def sumOfLeftLeaves(self, root: Optional[TreeNode]) -> int:
        if root is None:
            return 0
        if root.left is None and root.right is None: #叶子节点的子树是空,所以左叶子之和也是空
            return 0
        left_sum = self.sumOfLeftLeaves(root.left)
        if root.left and not root.left.left and not root.left.right: #处理叶子节点,在父节点处相加
            left_sum = root.left.val
        right_sum = self.sumOfLeftLeaves(root.right)
        return left_sum+right_sum

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值