663. Equal Tree Partition

Given a binary tree with n nodes, your task is to check if it’s possible to partition the tree to two trees which have the equal sum of values after removing exactly one edge on the original tree.

Example 1:
Input:     
    5
   / \
  10 10
    /  \
   2   3
Output: True

思路: 先算一遍整棵树的sum,如果sum为奇数,则返回false,不可分
返回的Result中要包含:

  1. int _sum :左右子树的sum
  2. boolean _canSplit : 是否可分

左孩子 和 右孩子的答案拿到以后,算一下自己的sum 再看一下左子树是否可分,右子树是否可分,或者左子树的sum是否等于一半,右子树的sum是否等于一半。

class Solution {
    public boolean checkEqualTree(TreeNode root) {
        int sum = sum(root);
        if (sum % 2 != 0) {
            return false;
        }
        return dfs(root, sum / 2)._canSplit;
    }
    
    private int sum(TreeNode node) {
        if (node == null) {
            return 0;
        }
        return sum(node.left) + sum(node.right) + node.val;
    }
    
    private Result dfs(TreeNode node, int halfSum) {
        if (node == null) {
            return new Result(false, 0);
        }
        Result left = dfs(node.left, halfSum);
        Result right = dfs(node.right, halfSum);
        
        int sum = left._sum + right._sum + node.val;
        boolean canSplit = false;
        if (left._canSplit || right._canSplit 
            || (node.left != null && left._sum == halfSum)
            || (node.right != null && right._sum == halfSum)) {
            canSplit = true;
        }
        return new Result(canSplit, sum);
    }
    
    private class Result {
        boolean _canSplit;
        int _sum;
        public Result(boolean canSplit, int sum) {
            _canSplit = canSplit;
            _sum = sum;
        }
    }
}

遇到的坑:
不能这样来判断,加了自己的节点的sum后再判断是否等于halfSum,
case [0, -1, 1] 这种case不通过。

if (left._canSplit || right._canSplit || sum == halfSum) {
     canSplit = true;
}

二是此处判断奇数,不要使用sum % 2 == 1 因为有可能是负奇数。

int sum = sum(root);
if (sum % 2 != 0) {
    return false;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值