代码随想录 day13:第六章 二叉树 part03

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

  • 再一次涉及到,什么是高度,什么是深度
    在这里插入图片描述
  • 平衡二叉树定义为:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1
  • 二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数。
  • 二叉树节点的高度:指从该节点到叶子节点的最长简单路径边的条数。
  • 但leetcode中强调的深度和高度很明显是按照节点来计算的,如图:
    在这里插入图片描述
  • 关于根节点的深度究竟是1 还是 0,不同的地方有不一样的标准,leetcode的题目中都是以节点为一度,即根节点深度是1。但维基百科上定义用边为一度,即根节点的深度是0。
  • 求深度可以从上到下去查 所以需要前序遍历(中左右),而高度只能从下到上去查,所以只能后序遍历(左右中)
  • 递归三部曲:
    1. 明确递归函数的参数和返回值:参数:当前传入节点。 返回值:以当前传入节点为根节点的树的高度
    1. 明确终止条件:递归的过程中依然是遇到空节点了为终止,返回0,表示当前节点为根节点的树高度为0。
    1. 明确单层递归的逻辑:如何判断以当前传入节点为根节点的二叉树是否是平衡二叉树呢?当然是其左子树高度和其右子树高度的差值。分别求出其左右子树的高度,然后如果差值小于等于1,则返回当前二叉树的高度,否则返回-1,表示已经不是二叉平衡树了。
  • 如果左子树的高度计算结果为-1(意味着左子树不平衡)或者右子树的高度计算结果为-1(意味着右子树不平衡),那么就直接返回-1
class Solution:
    def get_height(self,root):
        if not root:
            return 0
        
        # left
        left=self.get_height(root.left)
        #right
        right=self.get_height(root.right)

        if left == -1 or right == -1 or abs(left - right) > 1:
            return -1
        return max(left,right)+1

    def isBalanced(self, root: Optional[TreeNode]) -> bool:
        return self.get_height(root)!=-1

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

在这里插入图片描述

  • 要求从根节点到叶子的路径,所以需要前序遍历,这样才方便让父节点指向孩子节点,找到对应的路径。
  • 第一次涉及到回溯,因为我们要把路径记录下来,需要回溯来回退一个路径再进入另一个路径。
    在这里插入图片描述
  • 先使用递归的方式,来做前序遍历。要知道递归和回溯就是一家的,本题也需要回溯。
  • 递归:
    1. 递归函数参数以及返回值:要传入根节点,记录每一条路径的path,和存放结果集的result,这里递归不需要返回值
    1. 确定递归终止条件:本题要找到叶子节点,当 cur不为空,其左右孩子都为空的时候,就找到叶子节点。
    1. 确定单层递归逻辑因为是前序遍历,需要先处理中间节点,中间节点就是我们要记录路径上的节点,先放进path中。
  • 将 path 的一个副本(通过 path[:] 来创建,避免修改原始的 path )传递进去。
class Solution:
    def traversal(self,cur,path,result):
        if not cur:
            return 
        path.append(cur.val)
        if not cur.left and not cur.right:# 终止条件
            result.append('->'.join(map(str,path)))
        #遍历条件
        if cur.left:
            self.traversal(cur.left,path[:],result)
        if cur.right:
            self.traversal(cur.right,path[:],result)

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

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

  • 搞清楚什么是左叶子,剩下的就是二叉树的基本操作。
    在这里插入图片描述
  • 首先要注意是判断左叶子,不是二叉树左侧节点,所以不要上来想着层序遍历。
    -左叶子的定义节点A的左孩子不为空,且左孩子的左右孩子都为空(说明是叶子节点),那么A节点的左孩子为左叶子节点
  • 判断当前节点是不是左叶子是无法判断的,必须要通过节点的父节点来判断其左孩子是不是左叶子。
  • 递归三部曲:
    1. 确定递归函数的参数和返回值:判断一个树的左叶子节点之和,那么一定要传入树的根节点,递归函数的返回值为数值之和
    1. 确定终止条件:如果遍历到空节点,那么左叶子值一定是0
    1. 确定单层递归的逻辑:当遇到左叶子节点的时候,记录数值,然后通过递归求取左子树左叶子之和,和 右子树左叶子之和,相加便是整个树的左叶子之和。
    def sumOfLeftLeaves(self, root: Optional[TreeNode]) -> int:
        if not root:
            return 0

        if not root.left and not root.right:
            return 0

        leftvalue=self.sumOfLeftLeaves(root.left)  # 左
        rightvalue=self.sumOfLeftLeaves(root.right)# 右
        if root.left and not root.left.left and not root.left.right:# 左子树是左叶子的情况
            leftvalue=root.left.val

        return leftvalue + rightvalue 

222.完全二叉树的节点个数(优先掌握递归)

  • 需要了解,普通二叉树 怎么求,完全二叉树又怎么求
    在这里插入图片描述
class Solution:
    def countNodes(self, root: TreeNode) -> int:
        return self.getNodesNum(root)
        
    def getNodesNum(self, cur):
        if not cur:
            return 0
        leftNum = self.getNodesNum(cur.left) #左
        rightNum = self.getNodesNum(cur.right) #右
        treeNum = leftNum + rightNum + 1 #中
        return treeNum
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值