代码随想录算法训练营 Day17|110.平衡二叉树, 257. 二叉树的所有路径, 404.左叶子之和

Day17|110.平衡二叉树, 257. 二叉树的所有路径, 404.左叶子之和

110.平衡二叉树

思路

平衡二叉树,左右子树的高度差不超过1。
后序遍历,如果一个节点的左节点和右节点的高度差不超过1,则返回最深的节点高度,通过左右中的方式,将结果向上传递。
尝试写代码:

class Solution:
    def isBalanced(self, root: Optional[TreeNode]) -> bool:
        if not root:
            return True # 不知道这里该写 True 还是 0

        left_heighgt = self.isBalanced(root.left)
        right_height = self.isBalanced(root.right)
        if abs(left_heighgt - right_height) > 1:
            return False
            height = max(left_heighgt, right_height) + 1
        return height
        return True

结果不对。
不清楚返回值如何写。每次如果返回了节点的高度值,就无法返回判断结果(True or False)

根据代码随想录视频
要点:

  1. 如果判断节点的左右子树高度差超过1, 则返回‘-1’
  2. 每次得到左子树或者右子树的高度时,先判断该值是不是‘-1’,如果是,直接返回‘-1’

根据视频写代码:

class Solution:
    def isBalanced(self, root: Optional[TreeNode]) -> bool:
        if not root:
            return 0

        left_heighgt = self.isBalanced(root.left)
        if left_heighgt == -1:
            return -1
        right_height = self.isBalanced(root.right)
        if right_height == -1:
            return -1
        if abs(left_heighgt - right_height) > 1:
            return -1
        else:
            height = max(left_heighgt, right_height) + 1
            return height

结果依旧不对。返回值是某个具体的数字,而不是题目要求的True或者False。

注意
此时可以重新创建一个函数,将之前的所有操作放进新函数中,在本身判断是否是平衡二叉树的函数中调用该函数。

最终代码:

class Solution:
    def isBalanced(self, root: Optional[TreeNode]) -> bool:
        if self.getHeight(root) == -1:
            return False
        else:
            return True

    def getHeight(self, root):
        if not root:
            return 0
        left_height = self.getHeight(root.left)
        if left_height == -1:
            return -1
        right_height = self.getHeight(root.right)
        if right_height == -1:
            return -1
        if abs(left_height - right_height) > 1:
            return -1
        else:
            height = max(left_height, right_height) + 1
            return height

257. 二叉树的所有路径

思路

没有思路,不知道如何写。
甚至不清楚应该用什么遍历顺序。

根据代码随想录视频
要点:

  1. 前序遍历,因为只有前序遍历,能让父节点指向孩子节点,输出最终的形式。
  2. 本题有回溯的过程
  3. 终止条件:如果节点的左右孩子都为空,则遍历到叶子节点,即收集到了一条完整的路径。
  4. 中左右,中代表处理过程。本题的“中”需要放在终止条件的上面,不然可能就return了
  5. 写到“左右”时,需要先判断是否存在左右节点
  6. 向左向右遍历后,写完递归,就要写回溯。这里的回溯,就是将之前push进来的节点再pop出去

尝试写代码

class Solution:
    def binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]:
        path = []
        result = []
        return self.traversal(root, path, result)
        
    def traversal(self, node, path, result):
        # 中
        path.append(str(node.val))
        # 终止条件
        if not node.left and not node.right:
            result.append('->'.join(path))
        # 左
        if node.left:
            self.traversal(node.left, path, result) 
            path.pop() # 回溯
        # 右
        if node.right:
            self.traversal(node.right, path, result)
            path.pop() # 回溯

        return result

历经多次debug,终于成功通过!

注意:
回溯函数可以没有返回值,因为参数中已经有最终结果了。

最终代码:

class Solution:
    def binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]:
        path = []
        result = []
        self.traversal(root, path, result)
        return result
        
    def traversal(self, node, path, result):
        # 中
        path.append(str(node.val))
        # 终止条件
        if not node.left and not node.right:
            result.append('->'.join(path))
        # 左
        if node.left:
            self.traversal(node.left, path, result) 
            path.pop() # 回溯
        # 右
        if node.right:
            self.traversal(node.right, path, result)
            path.pop() # 回溯
        return

Python函数map

使用map()函数,可以直接将列表中的所有值,全部转换为str

a=(1,2,3,4,5)
la=map(str,a)
# 输出:
# ['1', '2', '3', '4', '5']

404.左叶子之和

思路

用中序遍历,遍历左叶子后,在“中”的处理逻辑中,将左叶子的值加起来

尝试写代码:

class Solution:
    def sumOfLeftLeaves(self, root: Optional[TreeNode]) -> int:
        result = []
        self.traversal(root, result)
        return sum(result)

    def traversal(self, node, result):
        if not node.left and not node.right:
            return 
        if node.left:
            self.traversal(node.left, result)
        if node.left:
            result.append(node.left.val)
        if node.right:
            self.traversal(node.right, result)

结果错误,因为题目要求求出左叶子节点的和,上面代码算的是所有左节点之和。
该思路有问题。
不太清楚,如何将 该节点是否是左叶子节点 的判断放在哪里?如果放在终止条件中,该如何判断?

根据代码随想录视频:
要点:

  1. 判断左叶子节点时,无法在该叶子节点上判断,只能在该叶子节点的父节点上判断,即一个节点存在左节点,且其左节点的左右孩子为空。
  2. 使用后序遍历容易,因为可以讲结果一层层返回。

利用该逻辑写代码:

class Solution:
    def sumOfLeftLeaves(self, root: Optional[TreeNode]) -> int:
        result = []
        self.traversal(root, result)
        return sum(result)

    def traversal(self, node, result):
        if node.left:
            self.traversal(node.left, result)
        if node.right:
            self.traversal(node.right, result)
        if node.left and not node.left.left and not node.left.right:
            result.append(node.left.val)
            return

成功通过!
只是这种写法,如果直接将每个左叶子的值加入result中,最后虽然值是对的,但返回之后,result又变为0了。

注意:

  1. 这道题不需要额外定义函数,只用题目给的主函数就够了。

最终代码:

class Solution:
    def sumOfLeftLeaves(self, root):
        if root is None:
            return 0
        if root.left is None and root.right is None:
            return 0
        
        leftValue = self.sumOfLeftLeaves(root.left)  # 左
        if root.left and not root.left.left and not root.left.right:  # 左子树是左叶子的情况
            leftValue = root.left.val
            
        rightValue = self.sumOfLeftLeaves(root.right)  # 右

        sum_val = leftValue + rightValue  # 中
        return sum_val

总结:
需要重新写一遍代码

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值