leetcode算法训练十五天| 110.平衡二叉树,257. 二叉树的所有路径,404.左叶子之和

昨天休息了一天,和朋友们去城里喝咖啡打biliards去了,今天狂补两天的算法。

110. 平衡二叉树

学习视频:后序遍历求高度,高度判断是否平衡 | LeetCode:110.平衡二叉树_哔哩哔哩_bilibili

学习文档:代码随想录 (programmercarl.com)

学习时间:15:00-15:37

记录时间:15:37-15:56

状态:已听懂|可单独复写代码|暂时不复习

1. 看到问题后的初始想法与看完随想录后的心得

        看到这道题的第一反应是定义两个函数,第一个函数用来统计深度,第二个函数用来判断是否为二叉树。看了视频之后发现,这两个函数可以合并为一个(其实在刚开始思考的时候就感觉到可以合并,但因为我是在脑内编写代码所以还是感觉比较模糊没有仔细去想。)

这题依旧是递归方法,下面我将从递归的三个步骤中详细记录过程

  1. 递归函数的输入与输出:递归函数输入某个节点,输出平衡二叉树的高度(如果不为平衡二叉树,则输出-1)
  2. 递归函数的终止条件:遇到节点为空时,输出0
  3. 递归函数的单层步骤:首先得到左子树的高度,如果左子树高度为-1则输出-1,同理,得到右子树的高度,如果右子树高度为-1则输出-1(若左右子树不是平衡二叉树,则一定不是平衡二叉树)。若左右子树绝对高度差大于1,输出-1.若左右子树绝对高度差小于等于1,则输出左右子树节点的最大值并加上1.

最终代码如下:

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def isBalanced(self, root):
        """
        :type root: TreeNode
        :rtype: bool
        """
        def judgeBalance(root):
            if root is None:
                return 0
            left_height = judgeBalance(root.left)
            if left_height == -1:
                return -1
            right_height = judgeBalance(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)
        result = judgeBalance(root)
        if result == -1:
            return False
        else:
            return True
        

257. 二叉树的所有路径

学习视频:递归中带着回溯,你感受到了没?| LeetCode:257. 二叉树的所有路径_哔哩哔哩_bilibili

学习文档:代码随想录 (programmercarl.com)

学习时间:16:00-16:50

记录时间:16:50-17:30

状态:已听懂|可单独复写代码|暂时不复习

1. 看到问题后的初始想法与看完随想录后的心得

        本题是我首次遇到回溯算法,因此直接看视频开始学习。先前递归的时候我们不需要用到回溯算法是因为我们不需要保存每一次递归的路径/信息,只需要提取每一次递归的最大/最小/bool值即可。但在本题,我们需要用到二叉树遍历的所有路径,因此我们在遍历完一个点后,需要将那个点删除,以寻找其他点的其他路径。

  1. 递归的输入与输出:该递归的输入为寻找所有路径的根节点,记录当前路径的数组以及记录总路径的数组。
  2. 递归的终止条件:当该节点的左右孩子为空时,则将path放入result中,结束递推(直接写return即可)
  3. 递归的单层逻辑:首先在终止条件之前记录当前节点的数值,将其append进数组中。若节点的左孩子不为空,则遍历左孩子,全部找到后将该左孩子pop出数组(回溯),然后判断右孩子不为空,则遍历右孩子,全部遍历后将右孩子pop出数组(依旧是回溯)。在这里,pop出孩子的主要原因时因为我们已经遍历完该孩子的所有路径后,需要将这个孩子弹出,以遍历另一个孩子的所有路径(不弹出的话在遍历右孩子的时候会有个左孩子卡在里面,就出错了)

代码如下

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def binaryTreePaths(self, root):
        """
        :type root: TreeNode
        :rtype: List[str]
        """
        def getallpath(root, path, result):
            path.append(root.val)
            if root.left is None and root.right is None:
                string = ''
                for i in path:
                    string = string + str(i) + '->'
                string = string[:-2]
                result.append(string)
                return
            if root.left:
                getallpath(root.left, path, result)
                path.pop()
            if root.right:
                getallpath(root.right, path, result)
                path.pop()
        path = []
        result = []
        getallpath(root, path, result)
        return result

 404.左叶子之和 

学习视频:二叉树的题目中,总有一些规则让你找不到北 | LeetCode:404.左叶子之和_哔哩哔哩_bilibili

学习文档:代码随想录 (programmercarl.com)

学习时间:17:30-18:17

记录时间:18:17-

状态:已听懂|可单独复写代码|暂时不复习

1. 看到问题后的初始想法与看完随想录后的心得

        第一次靠自己做题做出递归的题目(挺腰)!我一开始的想法是在递归中传入两个参数,第一个是需要统计左叶子之和的根节点,第二个是bool值,用来判断是否是上一个根节点的左孩子。我这里就不详细说我自己的递归思路了,和卡哥的思路很像,每一层都是计算并返回左右子树的左叶子之和。我自己写的代码如下:

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def sumOfLeftLeaves(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        def getsum(root, left):
            if root is None:
                return 0 
            elif root.left is None and root.right is None and left is True:
                return root.val

            sumleft = getsum(root.left, True)
            sumright = getsum(root.right, False)
            return sumleft + sumright
            
        result = getsum(root, False)
        return result

而按照随想录中的代码,我们的递归思路如下:

  1. 递归的输入值与输出: 我们递归的输入值为要求左叶子之和的子节点,输出为左叶子之和
  2. 递归的终止条件:当当前节点为空或者当前节点的左右孩子为空,则输出0
  3. 递归的单层逻辑:先计算得到左孩子的左叶子之和,并且如果当前节点的左孩子为叶子节点(左右孩子为None),则将左叶子之和变为当前节点左孩子的val。然后再计算右孩子的左叶子之和。
# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def sumOfLeftLeaves(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        def getsum(root):
            if root is None:
                return 0
            if root.left is None and root.right is None:
                return 0
            leftsum = getsum(root.left)
            if root.left is not None and root.left.left is None and root.left.right is None:
                leftsum = root.left.val
            rightsum = getsum(root.right)
            return leftsum + rightsum
        result = getsum(root)
        return result

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值