day15-binary tree-part03-7.17

tasks for today:

1.110 平衡二叉树 (优先掌握递归)

2. 257 二叉树的所有路径(优先掌握递归)

3. 404.左子叶之和(优先掌握递归)

4. 完全二叉树的节点个数(优先掌握递归)

----------------------------------------------------------------------------------------

1.110 平衡二叉树 (优先掌握递归)

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

所以本质还是要求每个子节点的高度(后序遍历),但是要增加一些高度差的判断,如果超过1,那么代表不平衡,但是由于递归函数的返回量为高度,因此要用一个int来表示这种不平衡的情况,所以这里选择了用-1来代表,这样-1表示不平衡。

# 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:
        def nodeHight(node):
            if node is None:
                return 0
            leftH = nodeHight(node.left)
            rightH = nodeHight(node.right)
            if leftH == -1:
                return -1
            if rightH == -1:
                return -1
            
            hightdiff = abs(leftH - rightH)
            if hightdiff > 1:
                return -1
            else:
                return 1 + max(leftH, rightH)
        
        result = nodeHight(root)
        
        return False if result == -1 else True
            

本题如果想用迭代法,那么需要先另外定义一个函数来求深度,然后再按照层序遍历迭代方法进行平衡判断

2. 257 二叉树的所有路径(优先掌握递归)

本题第一次涉及回溯,采用前序遍历(中左右)方便令父节点指向子节点.

note:every time when there is recursive, there should be a trace back

# 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 binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]:
        def findPath(node, path, result):
            # mid
            path.append(node.val)
            if node.left is None and node.right is None:
                result.append('->'.join(map(str, path)))
            
            # left
            if node.left:
                findPath(node.left, path, result)
                # trace back, every time when there is recursive, there should be a trace back
                path.pop()

            # right
            if node.right:
                findPath(node.right, path, result)
                # trace back
                path.pop()
        
        path = []
        result = []
        findPath(root, path, result)

        return result

本题同样也可以用层序遍历,bfs广度优先方法,但是需要一个另外的stack来进行路径的存储,注意这个stack中的每个元素都是一个路径字符串,但是并不是完整的,只有当到达最后的字节点才会被push进result中

3. 404.左子叶之和(优先掌握递归)

首先要注意是判断左叶子,不是二叉树左侧节点,所以不要上来想着层序遍历。

因为题目中其实没有说清楚左叶子究竟是什么节点,那么我来给出左叶子的明确定义:节点A的左孩子不为空,且左孩子的左右孩子都为空(说明是叶子节点),那么A节点的左孩子为左叶子节点.

Here is the BFS version, 层序遍历。

Note:pay attention to this calculation logic, not adding up all the left side node's value.

# 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 root.left is None and root.right is None:
            return 0
        nodeQueue = collections.deque([root])
        result = 0
        while nodeQueue:
            cur = nodeQueue.popleft()
            # pay attention to this calculation logic, not adding up all the left side node's value.
            if cur.left and not cur.left.left and not cur.left.right:
                result += cur.left.val
            if cur.left:
                nodeQueue.append(cur.left)
            if cur.right:
                nodeQueue.append(cur.right)
        
        return result

recursive methods

need to pay attention to when the leftLeftsum shoule be replaced by the node.left.val

# 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:
        def leftchildsum(node):
            if node is None:
                return 0
            if node.left is None and node.right is None:
                return 0

            leftLeftsum = leftchildsum(node.left)
            if node.left and not node.left.left and not node.left.right:
                leftLeftsum = node.left.val
            rightLeftsum = leftchildsum(node.right)

            sumval = leftLeftsum + rightLeftsum

            return sumval
        
        return leftchildsum(root)

A summary for this practice:

这道题目要求左叶子之和,其实是比较绕的,因为不能判断本节点是不是左叶子节点。

此时就要通过节点的父节点来判断其左孩子是不是左叶子了。

平时我们解二叉树的题目时,已经习惯了通过节点的左右孩子判断本节点的属性,而本题我们要通过节点的父节点判断本节点的属性。

4. 完全二叉树的节点个数(优先掌握递归)

层序遍历,bfs

# 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 root is None:
            return 0
        nodeQueue = collections.deque([root])
        result = 0
        while nodeQueue:
            cur = nodeQueue.popleft()
            result += 1
            if cur.left:
                nodeQueue.append(cur.left)
            if cur.right:
                nodeQueue.append(cur.right)
        
        return result

as for the dfs, two methods are provided as below: one is do append and calculate the length of list, the other one is directly calculate the number of nodes

# 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:
        # method 1
        result = []
        
        def travese(node, sumnodes):
            if node == None:
                return
            
            sumnodes.append(node.val)
            travese(node.left, sumnodes)
            travese(node.right, sumnodes)
        
        travese(root, result)

        return len(result)

        # method 2
        def travese(node):
            if node is None:
                return 0
            left = travese(node.left)
            right = travese(node.right)
            sumnodes = left + right + 1

            return sumnodes
        
        return travese(root)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值