When I first see this question, I was thinking about whether top-down or bottom-up recursion should be applied. Obviously, you cannot pass down the count of subtrees using top-down method.
For bottom-up method, the base case is the leaf nodes. we use root.left ==null && root.right ==null to verify whether it's a leaf node.
A uni subtree means all the nodes have the same value, which tells us:
current node value = some value in left tree = some value is the right tree && left tree is uni && right tree is uni (IMPORTANT!! I didn't include uni subtrees as a necessary condition so I get the wrong answer in trees like [1,2,null,2,3]
Therefore, for each node, we need to consider:
1. whether it's a leaf node, if it is, the count ++ and return true;
2. Get two boolean flag boo1 and boo2, set them to true(for cases there's no left/right subtree)
3. whether it has a left subtree. if it does: if it's uni, set boo1 to T; if it's not uni, set boo1 to F. If the current value is not equal to a value in left subtree, set boo1 to F.
3. whether it has a right subtree. if it does: if it's uni, set boo2 to T; if it's not uni, set boo2 to F. If the current value is not equal to a value in right subtree, set boo2 to F.
4. See boo1&&boo2 whether they are false, if so return false; if not count++ and return true;
We use boolean as our recursion return because, it's impossible to decide whether the current node is a root of uni tree only based on only one previous layer value. If any previous layer violates the rule unisubtree, the current node will not be uni. Therefore, we need to use boolean as return to keep track of the global state.
The code:
int count = 0;
public int countUnivalSubtrees(TreeNode root) {
if(root == null) return 0;
helper(root);
return count;
}
public boolean helper(TreeNode root){
if(root.left == null && root.right == null) {
count++;
return true;
}
boolean boo1 = true;
boolean boo2 = true;
if(root.left != null){
boo1 = helper(root.left) && (root.val == root.left.val) ;
}
if(root.right != null){
boo2 = helper(root.right) &&(root.val == root.right.val);
}
if((boo1&&boo2) == false){
return false;
}
count++;
return true;
}