Count Univalue Subtrees
Question
Given a binary tree, count the number of uni-value subtrees.
A Uni-value subtree means all nodes of the subtree have the same value.
Solution
第一次寫的時候,寫了一個錯誤的寫法,但也只剩 6 個 test case 沒過。那時的想法是,寫個 recursion 去判斷,如果 root.val == root.left.val && root.val == root.right.val,就等於是 uni-value tree。但這樣的思路很明顯是不對的,因為這樣寫等於只檢查當前跟下面那層,但並沒有確認到整棵樹。
後來換了個寫法就 accept 了。我等於用了兩層 recursion。概念是,我先等左子樹跟右子樹判斷完,如果兩邊都回給我 true,那就表示那兩邊都是 uni-value subtree,接著再判斷 root 的值跟左右子樹是否相同。
    public int countUnivalSubtrees(TreeNode root) {
        if (root == null) {
            return 0;
        } else if (root.left == null && root.right == null) {
            return 1;
        }
        boolean left = helper(root.left);
        boolean right = helper(root.right);
        if (root.left != null && root.right == null) {
            if (left && root.val == root.left.val) {
                return 1 + countUnivalSubtrees(root.left);
            } else {
                return countUnivalSubtrees(root.left);
            }
        } else if (root.left == null && root.right != null) {
            if (right && root.val == root.right.val) {
                return 1 + countUnivalSubtrees(root.right);
            } else {
                return countUnivalSubtrees(root.right);
            }
        }
        return (root.val == root.left.val && root.val == root.right.val && left && right) ? 1 + countUnivalSubtrees(root.left) + countUnivalSubtrees(root.right) : countUnivalSubtrees(root.left) + countUnivalSubtrees(root.right);
    }
    public boolean helper(TreeNode t) {
        if (t == null) {
            return false;
        } else if (t.left == null && t.right == null) {
            return true;
        }
        if (t.left != null && t.right == null) {
            if (t.val != t.left.val) {
                return false;
            } else {
                return helper(t.left);
            }
        } else if (t.right != null && t.left == null) {
            if (t.val != t.right.val) {
                return false;
            } else {
                return helper(t.right);
            }
        }
        if (t.val != t.left.val || t.val != t.right.val) {
            return false;
        } 
        return helper(t.left) && helper(t.right);
    }
參考了解答,也是類似思路,只是寫的比較 concise。
    public int countUnivalSubtrees(TreeNode root) {
        int[] count = new int[1];
        helper(root, count);
        return count[0];
    }
    private boolean helper(TreeNode node, int[] count) {
        if (node == null) {
            return true;
        }
        boolean left = helper(node.left, count);
        boolean right = helper(node.right, count);
        if (left && right) {
            if (node.left != null && node.val != node.left.val) {
                return false;
            }
            if (node.right != null && node.val != node.right.val) {
                return false;
            }
            count[0]++;
            return true;
        }
        return false;
    }