day15 代码随想录 | 110 平衡二叉树 257 二叉树的所有路径 404 左叶子之和 222 完全二叉树的节点个数

110 平衡二叉树

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

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

这个题用递归的思路去解决,我们思考,他需要计算每个节点的左右两个子树的高度差

说的是高度,可以用后序遍历求高度

还是递归三部曲

1. 递归参数和返回值:递归参数就是节点,返回值就是高度

2. 递归中止条件:空节点,返回0。如果发现高度大于1  返回-1 

3. 单层递归

    得到左子树的高度

    判断是否为-1

   得到右子树的高度

  判断是否为-1

  确定最终高度 取最大高度。这里是核心,我们还是要返回一个高度

def isBalance(root):
    if not root:
        return True
    
    def dfs(root):
        if not root:
            return 0
        
        leftDepth = dfs(root.left)
        if leftDepth == -1:
            return -1
        rightDepth = dfs(root.right)
        if rightDepth == -1:
            return -1

        if abs(leftDepth-rightDepth) > 1:
            return -1
        else:
            depth = 1 + max(leftDepth, rightDepth)

            return depth
    
    return False if dfs(root) == -1 else True
        
        

257 二叉树所有路径

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

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

又是二叉树,这个题先考虑二叉树的遍历方式。其实从题意就能看到,从根节点开始,

那其实就是前序遍历 中左右。但是,你需要回溯,当你访问到叶子节点,记录之后,需要返回到你的父节点。

递归参数和返回值:递归参数有 节点,path 和存储path的结果。没有返回值

递归中止条件:并不是遍历到叶子节点或者 node==None就返回

如果cur != None and cur.left and cur.right 为None 说明是叶子节点,此时就得

操作path 将存储的节点路径添加进入result中,然后return

单层递归:

         中左右

         刚开始应该先将 当前节点 cur的值添加进path

         然后判断中止条件

        左子树找 并且回溯

       右子树找 并且回溯 回去的操作就是将path中的元素删除掉一个,你可以理解为删除当前节点。

def allPath(root):
    if not root:
        return []

    path = []
    result = []
    
    def dfs(root, path, result):
        path.append(root.val) # 中
        
        if root and root.left == None and root.right == None:
            res = "->".join(map(str, path))
            result.append(res)
            return 
        
        if cur.left:   # 左
            dfs(cur.left, path, result)
            path.pop() # 回溯

        if cur.right:  # 右
            dfs(cur.right, path, result)
            path.pop() # 回溯
    
    dfs(root, path, result)
    
    return result


        

404 左叶子之和

这个题理解左叶子,不是左子树的叶子。

你如何判断是左叶子呢,靠叶子节点是没办法,考虑父节点

假设父节点是parent. 判断是左叶子,那就是 parent.left and parent.left.left == None and parent.left.right==None。

仍然采用递归

递归参数和返回值:递归参数是节点 返回值是求和

递归中止条件:if not node: return 0  if root.left == None and root.right==None return0

即使是叶子节点,也返回0,你不能直接加叶子节点,这时的叶子节点无法判断是左叶子

单层递归:

              采用 左右中的遍历顺序

             因此你要对节点求和。你不能一来就求和

def sumOfValues(root):
    if not root:
        return 0
    if root.left == None and root.right == None:
        return 0

    leftValue = sumOfValues(root.left) # 左
    
    if root.left and root.left.left == None and root.left.right == None:
        leftValue = root.left.val

    rightValue = sumOfValues(root.right) # 右

    
    sum_ = leftValue + rightValue # 中

    return sum_

        

222 完全二叉树的节点个数

这个题其实就是求二叉树的节点个数的变种

你可以用层次遍历,也可以用一般求二叉树的解法(递归 左右中)。

但是这个题的目的肯定是要考察完全二叉树的性质。

求一般二叉树解法

递归参数和返回值: 返回的是整数值,参数就节点

中止条件:if not node: return 0

单层递归:

        左右中

 

def getNodeSum(root):
    def dfs(root)
        if not root:
            return 0
        left = getNodeSum(root.left)
        right = getNodeSum(root.right)
        sum_ = 1 + left + right
        return sum_
    return dfs(root)

使用完全二叉树的特性,在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2^(h-1)  个节点。

完全二叉树只有两种情况,情况一:就是满二叉树,情况二:最后一层叶子节点没有满。

对于情况一,可以直接用 2^树深度 - 1 来计算,注意这里根节点深度为1。

对于情况二,分别递归左孩子,和右孩子,递归到某一深度一定会有左孩子或者右孩子为满二叉树,然后依然可以按照情况1来计算

这里的关键在于如何判断一个左子树或者右子树是不是满二叉树?

在完全二叉树中,如果递归向左遍历的深度等于递归向右遍历的深度,那说明就是满二叉树

def getNodeNum(root):
    if not root:
        return 0
    left = root.left
    right = root.right
    count = 1

    while left and right:
        count += 1
        left = left.left
        right = right.right
    
    if left == None and right == None: # 如果同时到底说明是满二叉树,反之则不是
        return 2 ** count - 1
    
    # 如果不是满二叉数 正常遍历 左右中
    left = getNodeNum(root.left)
    right = getNodeNum(root.right)

    sum_ = left + right + 1
    return sum_
    

  • 17
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值