Leetcode日练笔记41 [二叉树recursion专题] #250 Count Univalue Subtrees /Medium {Python}

Given the root of a binary tree, return the number of uni-value 

subtrees

.

uni-value subtree means all nodes of the subtree have the same value.

Example 1:

Input: root = [5,1,5,5,5,null,5]
Output: 4

Example 2:

Input: root = []
Output: 0

Example 3:

Input: root = [5,5,5,5,5,null,5]
Output: 6

Constraints:

  • The number of the node in the tree will be in the range [0, 1000].
  • -1000 <= Node.val <= 1000

Thought process:

Instinctively I take the main funciton countUnivalSubtrees as the one that should be recurred. So I divide the function into usual parts: one for base case which has no child nodes, automatically being a unival subtree, therefore counting as one; the rest part for recursive. 

# 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 countUnivalSubtrees(self, root: Optional[TreeNode]) -> int:
        if not root: return 0
        
        if not root.left and not root.right: return 1
        
        if not root.left:
            if root.right.val == root.val: 
                return 1 + self.countUnivalSubtrees(root.right)
            else:
                return self.countUnivalSubtrees(root.right)
        
        if not root.right:
            if root.left.val == root.val: 
                return 1 + self.countUnivalSubtrees(root.left)
            else:
                return self.countUnivalSubtrees(root.left)
        
        if root.right.val == root.val and root.left.val == root.val:
            return 1 + self.countUnivalSubtrees(root.right) + self.countUnivalSubtrees(root.left)
        else:
            return self.countUnivalSubtrees(root.right) + self.countUnivalSubtrees(root.left)
        

However, it misses the scenerio that even when the node of interest has the same value as its child node, it doesn't necessarily mean its child node itself is also a unival subtree. In such case, the node of interest may violate the rule of being a unival subree. So we can't use this approach.

Just like the graph shown below. This approach takes the root node 1 as unival subtree bc both its children nodes have the same value as it, which should not be by definition.

Therefore, we have to separate the responsibilities: 1)identify whether the node of interest is a unival subtree by traversing all its children nods n comparing their value; 2) count the nodes that are satisfied such criteria.

# 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 countUnivalSubtrees(self, root: Optional[TreeNode]) -> int:
        self.count = 0

        def is_a_uni_value_subtree(node)-> bool:

            if not node: return True
            
            isLeftUniValue = is_a_uni_value_subtree(node.left)
            isRightUniValue = is_a_uni_value_subtree(node.right)

            if isLeftUniValue and isRightUniValue:
                if node.left and node.left.val != node.val:
                    return False
                if node.right and node.right.val != node.val:
                    return False

                self.count += 1
                return True
            
            return False

        is_a_uni_value_subtree(root)
        return self.count
   

Explanation:
 

Here, the recursive calls are part of a conditional and statement. The nature of the and operator in Python (and many other languages) is short-circuiting. This means that if the first condition (is_a_uni_value_subtree(node.left)) evaluates to False, the second condition (is_a_uni_value_subtree(node.right)) will not be evaluated at all.

This short-circuiting can lead to parts of the tree not being visited. Specifically, if any node's left subtree is not a uni-value subtree, the right subtree won't even be checked, leading to potential uni-value subtrees being missed.

So, in the second code, the recursive exploration of the tree can be prematurely halted due to the short-circuiting behavior of the and operator, leading to a different (and likely incorrect) count of uni-value subtrees.

That's why we need to run both left child node and right child node first then put them into the conditional statement. So that we won't miss counting the right child node even the left child node is not a unival subtree.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值