The Equal Tree Partition problem asks you to determine whether it is possible to split a given binary tree into two trees with equal sum by removing exactly one edge. You are given the root node of a binary tree, where each node contains an integer value. Your task is to check if there exists a way to remove one edge (i.e., cut the tree into two subtrees) such that the sum of the values of the nodes in both resulting trees is the same.
TreeNode
object representing the root of the binary tree.
true
if such a partition exists, false
otherwise.
To solve this problem, let's start by understanding what it means to partition the tree. If we remove an edge, we get two subtrees. For the partition to be "equal," the sum of all node values in each subtree must be the same.
The brute-force way would be to try every possible edge removal, calculate the sum of both resulting trees, and check if they are equal. However, this is inefficient because recalculating subtree sums repeatedly is time-consuming.
Instead, we notice that if the total sum of the tree is T
, then after removing an edge, the sums of the two resulting trees must both be T/2
. So, the problem reduces to checking if there exists a subtree (other than the whole tree itself) whose sum is exactly T/2
.
This leads us to a more efficient approach: traverse the tree once to compute the total sum, then traverse again to check for a subtree with sum T/2
.
totalSum
.
totalSum
is odd, it's impossible to split into two equal integers, so return false
.
totalSum / 2
.
totalSum / 2
, return true
.
Consider the following example tree:
5 / \ 10 10 / \ 2 3
5 + 10 + 10 + 2 + 3 = 30
30 / 2 = 15
10 + 2 + 3 = 15
.
true
.
O(N^2)
time, where N
is the number of nodes.
O(N)
for recursion stack.
O(N)
), and again to check for the partition (O(N)
), so total time is O(N)
.
O(N)
for storing subtree sums and recursion stack.
The Equal Tree Partition problem is elegantly solved by reducing it to checking if any subtree sums to half the total tree sum. By leveraging post-order traversal and set storage, we avoid redundant computations and achieve linear time complexity. The key insight is recognizing that removing an edge is equivalent to isolating a subtree, and the sum check naturally follows. This approach is both efficient and easy to implement, making it a robust solution for binary tree partitioning challenges.
# Definition for a binary tree node.
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution:
def checkEqualTree(self, root: TreeNode) -> bool:
subtree_sums = []
def get_sum(node):
if not node:
return 0
s = node.val + get_sum(node.left) + get_sum(node.right)
subtree_sums.append(s)
return s
total = get_sum(root)
# Remove the total sum (whole tree) from consideration
subtree_sums.pop()
if total % 2 != 0:
return False
return (total // 2) in subtree_sums
// Definition for a binary tree node.
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
class Solution {
public:
bool checkEqualTree(TreeNode* root) {
vector<int> subtreeSums;
int total = getSum(root, subtreeSums);
// Remove the sum of the whole tree
subtreeSums.pop_back();
if (total % 2 != 0) return false;
for (int s : subtreeSums) {
if (s == total / 2) return true;
}
return false;
}
private:
int getSum(TreeNode* node, vector<int>& sums) {
if (!node) return 0;
int s = node->val + getSum(node->left, sums) + getSum(node->right, sums);
sums.push_back(s);
return s;
}
};
// Definition for a binary tree node.
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
class Solution {
private List<Integer> subtreeSums = new ArrayList<>();
public boolean checkEqualTree(TreeNode root) {
int total = getSum(root);
// Remove the sum of the whole tree
subtreeSums.remove(subtreeSums.size() - 1);
if (total % 2 != 0) return false;
return subtreeSums.contains(total / 2);
}
private int getSum(TreeNode node) {
if (node == null) return 0;
int s = node.val + getSum(node.left) + getSum(node.right);
subtreeSums.add(s);
return s;
}
}
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {boolean}
*/
var checkEqualTree = function(root) {
const subtreeSums = [];
function getSum(node) {
if (!node) return 0;
const s = node.val + getSum(node.left) + getSum(node.right);
subtreeSums.push(s);
return s;
}
const total = getSum(root);
subtreeSums.pop(); // remove the total sum (whole tree)
if (total % 2 !== 0) return false;
return subtreeSums.includes(total / 2);
};