Equal Tree Partition

本文探讨了一种算法,用于检查是否能通过移除一条边将给定的二叉树分割成两个子树,这两个子树的节点值之和相等。通过递归更新每个节点值,最终判断根节点值的一半是否存在于节点值的映射中。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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
Explanation: 
    5
   / 
  10
      
Sum: 15

   10
  /  \
 2    3

Sum: 15

 

Example 2:

Input:     
    1
   / \
  2  10
    /  \
   2   20

Output: False
Explanation: You can't split the tree into two trees with equal sum after removing exactly one edge on the tree.

 

这道题让我们划分等价树,就是说当移除一条边后,被分成的两棵树的结点之和需要相等。那么通过观察题目中的例子我们可以发现,如果我们将每个结点的结点值变成其所有子结点的结点值之和再加上当前的结点值,那么对于例子1来说,根结点的结点值就变成了30,断开位置的结点就变成了15,那么我们就可以发现其实只要断开位置的结点值是根结点值的一半,就存在等价划分。所以这道题的难点就是更新每个结点的结点值,我们可以使用递归来做。博主最开始使用的是unordered_set,把更新后的每个结点值都存入集合中,但是对于test case: [0, 1, -1] 会fail, 仔细分析下这个case,发现更新后的根结点值还是0,而且0已经被存入集合了,而0除以2还是0,在集合中存在,会返回true,但其实这棵树是不能等价划分的。0的情况确实比较特殊,所以我们使用unordered_map,建立更新后的结点值和其出现次数之间的映射,这样只有map中0的个数大于1的时候,才返回true。这样完美的避开了根结点为0的陷阱,Perfect!参见代码如下:

class Solution {
public:
    bool checkEqualTree(TreeNode* root) {
        unordered_map<int, int> m;
        int sum = helper(root, m);
        if (sum == 0) return m[0] > 1;
        return sum % 2 == 0 && m.count(sum / 2);
    }
    int helper(TreeNode* node, unordered_map<int, int>& m) {
        if (!node) return 0;
        int cur = node->val + helper(node->left, m) + helper(node->right, m);
        ++m[cur];
        return cur;
    }
};


### LeetCode Hot 100 Problems 列表 LeetCode 的热门题目列表通常由社区投票选出,涵盖了各种难度级别的经典编程挑战。这些题目对于准备技术面试非常有帮助。以下是部分 LeetCode 热门 100 题目列表: #### 数组与字符串 1. **两数之和 (Two Sum)** 2. **三数之和 (3Sum)** 3. **无重复字符的最长子串 (Longest Substring Without Repeating Characters)** 4. **寻找两个正序数组的中位数 (Median of Two Sorted Arrays)** #### 动态规划 5. **爬楼梯 (Climbing Stairs)** 6. **不同的二叉搜索树 (Unique Binary Search Trees)** 7. **最大子序列和 (Maximum Subarray)** #### 字符串处理 8. **有效的括号 (Valid Parentheses)** 9. **最小覆盖子串 (Minimum Window Substring)** 10. **字母异位词分组 (Group Anagrams)** #### 图论 11. **岛屿数量 (Number of Islands)** 12. **课程表 II (Course Schedule II)** #### 排序与查找 13. **最接近原点的 K 个点 (K Closest Points to Origin)** 14. **接雨水 (Trapping Rain Water)** 15. **最长连续序列 (Longest Consecutive Sequence)[^2]** #### 堆栈与队列 16. **每日温度 (Daily Temperatures)** 17. **滑动窗口最大值 (Sliding Window Maximum)** #### 树结构 18. **验证二叉搜索树 (Validate Binary Search Tree)** 19. **二叉树的最大路径和 (Binary Tree Maximum Path Sum)** 20. **从前序与中序遍历序列构造二叉树 (Construct Binary Tree from Preorder and Inorder Traversal)** #### 并查集 21. **冗余连接 II (Redundant Connection II)** #### 贪心算法 22. **跳跃游戏 (Jump Game)** 23. **分割等和子集 (Partition Equal Subset Sum)** #### 双指针技巧 24. **环形链表 II (Linked List Cycle II)[^1]** 25. **相交链表 (Intersection of Two Linked Lists)** #### 其他重要题目 26. **LRU缓存机制 (LRU Cache)** 27. **打家劫舍系列 (House Robber I & II)** 28. **编辑距离 (Edit Distance)** 29. **单词拆分 (Word Break)** 此列表并非官方发布版本而是基于社区反馈整理而成。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值