代码随想录算法训练营第十五天| 110.平衡二叉树 257. 二叉树的所有路径 404.左叶子之和 222.完全二叉树的节点个数

写在前边的话

        今天是代码随想录的第三天,今天训练的主要方法还是递归法,因此我就采取先想思路然后看视频讲解分析总结的步骤啦。前边总结了要先想想遍历顺序,要记得呀,那就开始啦!

        二叉树基础知识

110.平衡二叉树 

题目链接

        力扣题目链接

题目难度

        简单

文章讲解

        代码随想录文章讲解

视频讲解

        代码随想录视频讲解

递归法解题思路

        1. 遍历顺序:后序

        2. 递归三步曲:

                1)入参:二叉树当前节点;返回值:当前节点的最大深度。

                2)终止条件:节点为空,返回0。

                3)单次递归逻辑:分别获取左右孩子的最大深度,如果深度为-1表示已经不是平衡二叉树了则返回-1;计算左右孩子的最大深度差值,差值大于1则不是平衡二叉树返回-1,否则父亲节点的深度为1+max(左孩子的最大深度,右孩子的最大深度)。

代码编写

        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 isBalanced(self, root: Optional[TreeNode]) -> bool:
        if not root:
            return True
        if self.getHeigth(root) == -1:
            return False
        else:
            return True


    def getHeigth(self, node):
        if not node:
            return 0

        left_heigth = self.getHeigth(node.left)
        if left_heigth == -1:
            return -1
        right_heigth = self.getHeigth(node.right)
        if right_heigth == -1:
            return -1

        if abs(left_heigth - right_heigth) > 1:
            return -1
        else:
            return 1+max(left_heigth, right_heigth)
        java

257. 二叉树的所有路径

题目链接

        力扣题目链接

题目难度

        简单

文章讲解

        代码随想录257. 二叉树的所有路径文章讲解

视频讲解

        代码随想录257. 二叉树的所有路径视频讲解

递归法解题思路

        递归+回溯

        1. 遍历顺序:前序遍历,这样才能形成题目描述的那样使得父亲节点指向孩子节点,从而生成对应的路径。

        2. 递归三步曲:

                1)入参:当前节点,保存当前路径的数组path,保存全部路径的数组res。返回:保存全部路径的数组res。

                2)终止条件:注意不是node为None的时候了,而是如果当前节点的左右孩子都为None就终止了。

                3)单次递归逻辑::保存当前节点的值到path,这个时候就需要检查下当前节点的左右孩子是不是为空,如果为空则当前路径结束,把path里数据生成路径并保存到res中,当次递归也就终止了;否则的话遍历孩子:如果左孩子不为空则对左孩子进行递归逻辑直到这条路径结束,此时就要回溯节点了,要回溯到父亲节点;回溯到父亲节点以后就要遍历孩子了:如果右孩子不为空,则对右孩子进行递归逻辑直到这条路径结束,然后依然也要回溯到父亲节点。

注意:回溯和递归是一一对应的,有一个递归,就要有一个回溯。

代码编写

        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 trversal(self, node, path, res):
        path.append(str(node.val))  # 中
        if not node.left and not node.right:
            res.append("->".join(path))
            return

        if node.left:   # 左
            self.trversal(node.left, path, res)
            path.pop()  # 回溯
        if node.right:  # 右
            self.trversal(node.right, path, res)
            path.pop()  # 回溯

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

404.左叶子之和

题目链接

                力扣题目链接

题目难度

        简单

文章讲解

        代码随想录404. 左叶子之和

视频讲解

        代码随想录404.左叶子之和视频讲解

递归法解题思路

        1. 遍历顺序:后序遍历

        2. 递归三步曲:

                1)入参:二叉树根节点;返回值:左叶子节点之和

                2)终止条件:当前节点为空返回0;当前节点的左右孩子都为空返回0。

                3)单次递归逻辑:遇到叶子节点记录叶子节点的数值。通过递归求左子树左叶子节点之和和右子树左叶子节点之和,最后再相加。

代码编写

        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 sumOfLeftLeaves(self, root: Optional[TreeNode]) -> int:
        if not root:
            return 0

        if not root.left and not root.right:
            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)   # 右
        res = left_sum + right_sum   # 中
        return res 
        java

222.完全二叉树的节点个数

题目链接

        力扣题目链接

题目难度

        简单

文章讲解

        代码随想录222.完全二叉树的节点个数文章讲解

视频讲解

        代码随想录222.完全二叉树的节点个数视频讲解

递归法解题思路

        1. 遍历顺序:后序遍历

        2. 递归三步曲:(普通二叉树)

                1)入参:根节点;返回值:节点数量

                2)终止条件:节点空,返回0,即节点数是0

                3)单次递归逻辑:分别获取左右子树的节点数,最后求和加1就是二叉树的总节点数。

          递归三部曲:(完全二叉树)

                 1)入参:根节点;返回值:节点数量

                2)终止条件:节点空,返回0;分别一直往左和一直往右遍历节点并记录左子树深度和右子树深度,如果深度相同说明子树是满二叉树则用公式2^k-1计算节点数量。

                3)单次递归逻辑:分别获取左右子树的节点数,最后求和加1就是二叉树的总节点数。

代码编写

        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 getNodesNum(self, node):
        if not node:
            return 0

        left_num = self.countNodes(node.left)     # 左
        right_num = self.countNodes(node.right)   # 右
        res = left_num + right_num + 1            # 中
        return res

    def countNodes(self, root: Optional[TreeNode]) -> int:
        return self.getNodesNum(root)


# *************************************************************


# 完全二叉树
# 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 countNodes(self, root: Optional[TreeNode]) -> int:
        if not root:
            return 0
        
        left_depth = 0
        right_depth = 0
        left = root.left
        right = root.right
        while left:
            left_depth += 1
            left = left.left

        while right:
            right_depth += 1
            right = right.right

        if left_depth == right_depth:
            print(f"left_depth: {left_depth}")
            # return 2**(left_depth+1)-1
            return (2<<left_depth) - 1

        left_num = self.countNodes(root.left)     # 左
        right_num = self.countNodes(root.right)   # 右
        res = left_num + right_num + 1            # 中
        return res

        
        java

今日总结

        今日的题目都是用递归方法解决的,加深了对于递归的理解,并且在练习过程中有意识的先去想遍历顺序,然后按照递归三步曲解题,但是发现自己对于单次递归的逻辑还是不太能够很好的梳理出来,感觉还是有的绕,后边继续加强连续吧。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值