代码随想录刷题营Day17(110:平衡二叉树,257:二叉树的所有路径,404:左叶子之和)

110:平衡二叉树

平衡二叉树的定义是:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。
那么也就是说,要使用一种遍历方法,先遍历两棵子树,然后再用这两个子树的高度做差,看看高度差是不是0 or 1。那就是要用后序遍历了。

class Solution:
    def isBalanced(self,root):
        def getHeight(node):
            if not node:#判断终止条件
                return 0
            left_height=getHeight(node.left)#遍历左子树,得到高度
            if left_height==-1:#如果是-1,就向上传递-1这个不是平衡二叉树的信息
                return -1
            right_height=getHeight(node.right)#同理左子树
            if right_height==-1:#同理左子树
                return -1
            if abs(left_height-right_height)>1:#拿到左右子树的高度,做一下高度差的结果
                return -1
            else:
                return max(left_height,right_height)+1#正常返回符合题目的高度
        result=getHeight(root)#输入开始的地方~
        if result!=-1:#做最终的结果判断
            return True
        else:
            return False

这个题解里面。我们把-1当作“不是二叉树”的信息返回,就可以了。不用管具体是高度差了多少。先遍历左子树,拿到左子树的结果,无非两种情况(不是平衡二叉树:-1;是平衡二叉树:0,1),如果不是,向上返回这个信息,这里的向上返回是指,直接向上个递归返回这个子树就不是平衡二叉树。这样就不会执行后面的逻辑,一但是拿了个-1,那么永远是-1,这个-1的逻辑将永远向上传递,直到输出。那么,右子树也同理。
做题的时候乐乐一直有个问题,就是不加:

            if left_height==-1:#如果是-1,就向上传递-1这个不是平衡二叉树的信息
                return -1

            if right_height==-1:#同理左子树
                return -1

行不行。
答案是不行,也就是说,必须每次得到左右子树的是不是平衡二叉树的时候,都要向上返回,而不能,任意让他去执行下面综合左右子树高度差的逻辑。

            if abs(left_height-right_height)>1:#拿到左右子树的高度,做一下高度差的结果
                return -1
            else:
                return max(left_height,right_height)+1#正常返回符合题目的高度

因为这样少考虑了一种情况就是:
在这里插入图片描述
也就是说不能随便让进abs()中的逻辑,必须保证左子树和右子树都是符合平衡二叉树的规定才可以。如果左右子树不是平衡二叉树,那就直接向上返回就好了,不用走下面的逻辑。所以,必须左子树和右子树,得到他们的高度之后,有个判断,如果是-1,直接向上返回!
觉得这个题挺难的,但还是easy的评级,哎,是自己太菜了吧。


257:二叉树的所有路径

这个题需要进行回溯,回溯就是在递归之后紧接着一行,写回溯逻辑,一般是pop出数组值。

class Solution:
    def binaryTreePaths(self,root):
        path=[]
        res=[]
        def Traversal(node,path):
            path.append(node.val)
            if not node.left and not node.right:
                res.append(path[:])
            if node.left:
                Traversal(node.left,path)
                path.pop()
            if node.right:
                Traversal(node.right,path)
                path.pop()
            return res
        if not root:
            return res
        res=Traversal(root,path)
        new_path=[]
        for i in range(len(res)):
            new=""
            for j in res[i]:
                new=new+str(j)+"->"
            new_path.append(new[:-2])
        return new_path

关键:

            if node.left:
                Traversal(node.left,path)
                path.pop()
            if node.right:
                Traversal(node.right,path)
                path.pop()

中pop()操作!这样才能够完成1->2->5之后,把2,5弹出,在进入3,变成1->3。详细过程,等有空再画一个递归图应该就很明了了。


404:左叶子之和:

找到左叶子:
(1)该节点的左孩子和右孩子为空。
(2)该节点是其父节点的左孩子。

        sum_total=0
        def Traversal(node,sum_total):
            if not node:
                return 0
            if not node.left and not node.right:
                return 0
            left_sum=Traversal(node.left,sum_total)
            right_sum=Traversal(node.right,sum_total)
            cur_left=0
            if node.left and  not node.left.left and not node.left.right:
                cur_left=node.left.val
            sum_total=left_sum+right_sum+cur_left
            return sum_total
        sum_total=Traversal(root,sum_total)
        return sum_total

因为要收集一整棵二叉树的左叶子,所以,需要用后序遍历进行收集!先遍历左子树,在遍历右子树,收集两个子树的左叶子的和,然后中间的处理逻辑就是将当前几点都加起来,再向上返回左叶子的和。


总结:

觉得今天的题都好难啊,但都还是简单题,看来自己对递归的理解还是不能自如地去运用,才会觉得难吧。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值