均匀树划分
难度:
标签:
题目描述
代码结果
运行时间: 46 ms, 内存: 19.5 MB
/*
* Problem Statement:
* Given a binary tree, we need to determine if we can partition the tree into two subtrees with equal sum by removing exactly one edge.
* The function `checkEqualTree` should return true if such a partition is possible, otherwise false.
*/
import java.util.stream.Stream;
import java.util.stream.Collectors;
import java.util.HashMap;
import java.util.Map;
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
public class EqualTreePartitionStream {
// Helper method to calculate the sum of the entire tree
private int sumTree(TreeNode root) {
if (root == null) return 0;
return Stream.of(root.val, sumTree(root.left), sumTree(root.right)).mapToInt(Integer::intValue).sum();
}
// Main method to check if we can partition the tree into two equal sum subtrees
public boolean checkEqualTree(TreeNode root) {
if (root == null) return false;
int totalSum = sumTree(root);
// If the total sum is odd, we cannot partition the tree
if (totalSum % 2 != 0) return false;
Map<TreeNode, Integer> subtreeSums = new HashMap<>();
return canPartition(root, totalSum / 2, subtreeSums);
}
// Helper method to check if we can find a subtree with a given sum
private boolean canPartition(TreeNode node, int target, Map<TreeNode, Integer> subtreeSums) {
if (node == null) return false;
int currentSum = Stream.of(node.val, canPartitionSum(node.left, target, subtreeSums), canPartitionSum(node.right, target, subtreeSums)).mapToInt(Integer::intValue).sum();
subtreeSums.put(node, currentSum);
if (currentSum == target) {
subtreeSums.put(node, 0); // Reset the currentSum to prevent double counting
return true;
}
return false;
}
// Helper method to calculate the sum of the subtree
private int canPartitionSum(TreeNode node, int target, Map<TreeNode, Integer> subtreeSums) {
if (node == null) return 0;
return Stream.of(node.val, canPartitionSum(node.left, target, subtreeSums), canPartitionSum(node.right, target, subtreeSums)).mapToInt(Integer::intValue).sum();
}
}
解释
方法:
这个题解的思路是先对二叉树进行一次遍历,计算出每个节点的子树和,将其存储在对应节点的val属性中。然后再次遍历二叉树,查找是否存在一个节点,其子树和恰好等于整棵树的节点和的一半。如果找到了这样的节点,就说明可以将树划分为两棵和相等的子树。
时间复杂度:
O(n)
空间复杂度:
O(n)
代码细节讲解
🦆
在重新赋值节点的val属性为子树和时,原始的节点值信息会丢失。这样的设计是否会影响到其他可能的树操作或算法的实现?
▷🦆
你的算法在查找符合条件的节点时,是否考虑了根节点的子树和正好等于整棵树和一半的情况?如果根节点的子树和恰好等于整棵树的一半,这种情况如何处理?
▷🦆
如何处理整棵树的总和为奇数的情况?由于整数除以2可能得到浮点数,此时可能无法找到完全等于树总和一半的子树和。
▷🦆
算法中使用了全局变量self.ans来记录结果,这种设计方式是否最佳?是否有其他不使用全局变量的方法来传递或返回结果?
▷