[LeetCode] 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
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.
Note:
- The range of tree node value is in the range of [-100000, 100000].
- 1 <= n <= 10000
这道题让我们划分等价树,就是说当移除一条边后,被分成的两棵树的结点之和需要相等。通过观察题目中的例子可以发现,如果将每个结点的结点值变成其所有子结点的结点值之和再加上当前的结点值,那么对于例子1来说,根结点的结点值就变成了 30,断开位置的结点就变成了 15,可以发现其实只要断开位置的结点值是根结点值的一半,就存在等价划分。所以这道题的难点就是更新每个结点的结点值,可以使用递归来做。博主最开始使用的是 unordered_set,把更新后的每个结点值都存入集合中,但是对于 test case: [0, 1, -1] 会 fail, 仔细分析下这个 case,发现更新后的根结点值还是0,而且0已经被存入集合了,而0除以2还是0,在集合中存在,会返回 true,但其实这棵树是不能等价划分的。0的情况确实比较特殊,所以这里要使用 HashMap,建立更新后的结点值和其出现次数之间的映射,这样只有 HashMap 中0的个数大于1的时候,才返回 true。这样完美的避开了根结点为0的陷阱,Perfect!参见代码如下:
解法一:
class Solution {
public:
bool checkEqualTree(TreeNode* root) {
unordered_map<int, int> m;
int sum = helper(root, m);
if (sum == ) return m[] > ;
return (sum % == ) && m.count(sum / );
}
int helper(TreeNode* node, unordered_map<int, int>& m) {
if (!node) return ;
int cur = node->val + helper(node->left, m) + helper(node->right, m);
++m[cur];
return cur;
}
};
我们也可以使用 stack 来做,将所有的结点和存入到栈中,然后依次出栈,看是否有结点和正好等于 sum/2,这里还是要注意当 sum=0 的情况同时根结点值又正好是0的情况,最简单的处理办法就是将栈顶元素提前移除,这样就不会有 sum=sum/2 这种情况发生了,参见代码如下:
解法二:
class Solution {
public:
bool checkEqualTree(TreeNode* root) {
stack<int> st;
int sum = helper(root, st);
st.pop();
if (sum % != ) return false;
while (!st.empty()) {
if (st.top() == sum / ) return true;
st.pop();
}
return false;
}
int helper(TreeNode* node, stack<int>& st) {
if (!node) return ;
st.push(helper(node->left, st) + helper(node->right, st) + node->val);
return st.top();
}
};
Github 同步地址:
https://github.com/grandyang/leetcode/issues/663
参考资料:
https://leetcode.com/problems/equal-tree-partition/
LeetCode All in One 题目讲解汇总(持续更新中...)
[LeetCode] Equal Tree Partition 划分等价树的更多相关文章
- [LeetCode] 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 tw ...
- 663. Equal Tree Partition 能否把树均分为求和相等的两半
[抄题]: Given a binary tree with n nodes, your task is to check if it's possible to partition the tree ...
- 【LeetCode】663. Equal Tree Partition 解题报告 (C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 递归 日期 题目地址:https://leetcode ...
- LeetCode Same Tree (判断相同树)
题意:如题 思路:递归解决,同判断对称树的原理差不多.先保证当前两个结点是相等的,再递归保证两左结点是相等的,再递归保证右结点是相等的. /** * Definition for a binary t ...
- LeetCode: Binary Tree Traversal
LeetCode: Binary Tree Traversal 题目:树的先序和后序. 后序地址:https://oj.leetcode.com/problems/binary-tree-postor ...
- 【LeetCode】Symmetric Tree 推断一棵树是否是镜像的
题目:Symmetric Tree <span style="font-size:18px;"><span style="font-size:18px; ...
- 【LeetCode】208. Implement Trie (Prefix Tree) 实现 Trie (前缀树)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 公众号:负雪明烛 本文关键词:Leetcode, 力扣,Trie, 前缀树,字典树,20 ...
- [BZOJ3754]Tree之最小方差树
3754: Tree之最小方差树 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 402 Solved: 152[Submit][Status][Di ...
- 【LeetCode】86. Partition List 解题报告(Python)
[LeetCode]86. Partition List 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http:// ...
随机推荐
- 如何解决js递归里面出现的堆栈溢出
16.下面的递归代码在数组列表偏大的情况下会导致堆栈溢出.在保留递归模式的基础上,你怎么解决这个问题? var list = readHugeList(); var nextListItem = fu ...
- vue-过渡动画
本篇资料参考于官方文档: http://cn.vuejs.org/guide/transitions.html 概述: Vue 在跳转页面时,提供多种不同方式的动画过渡效果. ●in-out:新元素先 ...
- RabbitMQ 发布订阅持久化
RabbitMQ是一种重要的消息队列中间件,在生产环境中,稳定是第一考虑.RabbitMQ厂家也深知开发者的声音,稳定.可靠是第一考虑,为了消息传输的可靠性传输,RabbitMQ提供了多种途径的消息持 ...
- Beta 第五天
今天遇到的困难: 前端大部分代码由我们放逐的组员完成,这影响到了我们解决"Fragment碎片刷新时总产生的固定位置"的进程,很难找到源码对应 新加入的成员对界面代码不熟悉. 我们 ...
- 数据结构基础——指针及动态内存分配(malloc)
一.指针 C语言中的指针是一种数据类型,比如说我们用int *a;就定义了一个指针a,它指向一个int类型的数.但是这个指针是未初始化的,所以,一般的,我们都在创建指针时初始化它,以免出错,在还不吃的 ...
- 单向链表在O(1)时间内删除一个节点
说删链表节点,第一时间想到就是遍历整个链表,找到删除节点的前驱,改变节点指向,删除节点,但是,这样删除单链表的某一节点,时间复杂度就是O(n),不符合要求: 时间复杂度是O(n)的做法就不说了,看看O ...
- faster-rcnn 结构杂谈
faster-rcnn结构图: (只截取了最难理解的部分) 这个网络看似很复杂,但是理解了其中关键的层,就基本可以掌握这个结构了.要看源码!!要看源码!!要看源码 !!重要的事情说三遍. 关键的层: ...
- Python之旅_计算机基础入门
一.计算机基础 1.Python是编程语言 语言:一种事物与另一种事物沟通的介质. 编程语言:程序员与计算机沟通的介质. 什么是编程:程序员用编程语言把自己的逻辑思想下来,编程的结果就是一堆文件. 为 ...
- Mego开发文档 - 复杂保存操作
复杂保存操作 Mego框架还提供了更强大的数据更新API,以简化开发工作,同时也保证的性能. 指定属性添加数据 本列中指定插入一个数据对象,并且只会插入三列数据,最后两个属性是以表达式的形式插入. u ...
- PHP常用函数集合
PHP常用函数总结 数学函数 1.abs(): 求绝对值 $abs = abs(-4.2); //4.2 数字绝对值数字 2.ceil(): 进一法取整 echo ceil(9.999); // 10 ...