【LeetCode】979. Distribute Coins in Binary Tree 解题报告(C++)
作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/
题目地址:https://leetcode.com/problems/distribute-coins-in-binary-tree/
题目描述
Given the root
of a binary tree with N
nodes, each node
in the tree has node.val
coins, and there are N
coins total.
In one move, we may choose two adjacent nodes and move one coin from one node to another. (The move may be from parent to child, or from child to parent.)
Return the number of moves required to make every node have exactly one coin.
Example 1:
Input: [3,0,0]
Output: 2
Explanation: From the root of the tree, we move one coin to its left child, and one coin to its right child.
Example 2:
Input: [0,3,0]
Output: 3
Explanation: From the left child of the root, we move two coins to the root [taking two moves]. Then, we move one coin from the root of the tree to the right child.
Example 3:
Input: [1,0,2]
Output: 2
Example 4:
Input: [1,0,0,null,3]
Output: 4
Note:
- 1<= N <= 100
- 0 <= node.val <= N
题目大意
题目给出了一个二叉树,每个节点都有个数字代表当前节点有多少个金币,保证所有节点的金币数量之和等于节点个数。现在要求把金币平分到每个节点,使得每个节点都只放1个金币。问需要的移动次数是多少?
解题方法
递归
看到二叉树的题目我们一般想到递归,这个题也是如此。这个题是个难的的好题,确实很新颖。
首先,给定了一个二叉树的状态,只要不做重复移动,那么可以证明,移动是无状态的。也就是说,最终的移动次数不会因为先给谁后给谁,或者先移动几个再移动几个,再或者把某些金币移动到近的节点把另外一些金币移动到远的节点而有所不同。总之,我们可以放心大胆地,把金币移动到位,而不需要考虑把具体地金币移动到哪个确切的位置。
所以,我的思路就是分别统计左右子树缺少的金币个数,然后把每个节点和其子树总体的金币分配到位。累计所有节点和其子树所需要的移动次数就是结果。
每个子树缺少的金币数,等于节点数 - 金币数。因为题目确保了所有金币的和等于所有节点数,所以左子树缺少的金币数+该节点缺少的金币数+右子树缺少的金币数=0.我们每次把每个节点和其子树搞平衡,即左子树、该节点、右子树的节点数都等于金币数。注意此时,虽然左右子树总的不缺金币,但是内部仍然分配不均。所以,记录把这个节点搞平衡需要移动的金币数,然后累加上左子树和右子树搞平衡需要移动的金币数即为所求。
下面考虑,如果知道了左右子树需要的金币数,将他们搞平衡需要多少移动步数?答案是左右子树需要的金币数的绝对种子和。这个怎么理解?其实就是需要把子树多的金币挪给根节点,然后再从根节点分配给另一个缺少金币的子树对应的金币。举个栗子:
对于上面的树,左子树缺少-2个金币,右子树缺少1个金币。所以先把左子树多的那两个金币移动到根节点,然后根节点再给右子树分配缺的1个金币即可。因此总的移动次数是左右子树缺少的金币的和。
具体到代码,我们需要一个统计某个子树需要多少金币的函数need();需要计算把自身,左右子树都平衡,需要移动的coins个数的函数helper()。
因为代码比较简单,已经有注释,我就不讲代码了。
c++代码如下:
/**
* 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:
int distributeCoins(TreeNode* root) {
int res = 0;
helper(root, res);
return res;
}
// 统计把自身,左右子树都平衡,需要移动的coins个数
void helper(TreeNode* root, int& res) {
if (!root) return;
// 左、右子树缺多少
int left = need(root->left);
int right = need(root->right);
//左,右子树和自身都平衡需要的移动数
res += abs(left) + abs(right);
helper(root->left, res);
helper(root->right, res);
}
// 为了使该子树均匀,需要的coins数
// 节点数 - coins
int need(TreeNode* root) {
if (!root) return 0;
if (count_.count(root))
return count_[root];
int res = need(root->left) + 1 - root->val + need(root->right);
count_[root] = res;
return res;
}
private:
unordered_map<TreeNode*, int> count_;
};
日期
2019 年 1 月 20 日 —— 这次周赛有点简单
【LeetCode】979. Distribute Coins in Binary Tree 解题报告(C++)的更多相关文章
- LeetCode 979. Distribute Coins in Binary Tree
原题链接在这里:https://leetcode.com/problems/distribute-coins-in-binary-tree/ 题目: Given the root of a binar ...
- LC 979. Distribute Coins in Binary Tree
Given the root of a binary tree with N nodes, each node in the tree has node.val coins, and there ar ...
- 【leetcode】979. Distribute Coins in Binary Tree
题目如下: Given the root of a binary tree with N nodes, each node in the tree has node.val coins, and th ...
- 【LeetCode】993. Cousins in Binary Tree 解题报告(C++ & python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 DFS BFS 日期 题目地址:https://le ...
- 【LeetCode】543. Diameter of Binary Tree 解题报告 (C++&Java&Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 递归 日期 题目地址:https://leetcode ...
- LeetCode 606 Construct String from Binary Tree 解题报告
题目要求 You need to construct a string consists of parenthesis and integers from a binary tree with the ...
- LeetCode 104 Maximum Depth of Binary Tree 解题报告
题目要求 Given a binary tree, find its maximum depth. The maximum depth is the number of nodes along the ...
- 【LeetCode】863. All Nodes Distance K in Binary Tree 解题报告(Python)
[LeetCode]863. All Nodes Distance K in Binary Tree 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http ...
- 【LeetCode】297. Serialize and Deserialize Binary Tree 解题报告(Python)
[LeetCode]297. Serialize and Deserialize Binary Tree 解题报告(Python) 标签: LeetCode 题目地址:https://leetcode ...
随机推荐
- SQL-join(inner join)、left join、right join、full join
0.JOIN 类型 有时我们需要从两个或更多的表中获取结果,数据库中的表可通过键将彼此联系起来.每个表中都有一个主键,主键(Primary Key)是一个列,值都唯一.这样做的目的是在不重复每个表中的 ...
- SIG -MESH -1
协议栈 node:成为蓝牙mesh网络中一员的设备被称为节点(Node). 蓝牙mesh规格定义了节点可能拥有的特性.具有这些特性中的一个或多个,即表示节点可以在网络中扮演相应的特殊角色.定义的 ...
- vs2019 16.8更新之后的 C++20 协程co_yield用法
由于搜索出来的帖子,都是老版本的实验协程,很多老的代码已经失去参考性,并且很复杂,所以就自己研究了一下. 1 #include <iostream> 2 #include <coro ...
- C/C++ Qt 数据库QSql增删改查组件应用
Qt SQL模块是Qt中用来操作数据库的类,该类封装了各种SQL数据库接口,可以很方便的链接并使用,数据的获取也使用了典型的Model/View结构,通过MV结构映射我们可以实现数据与通用组件的灵活绑 ...
- 详解 Rainbond Ingress 泛解析域名机制
Rainbond 作为一款云原生应用管理平台,天生带有引导南北向网络流量的分布式网关 rbd-gateway.区别于一般的 Ingress 配置中,用户需要自行定义域名的使用体验,Rainbond 的 ...
- webservice--常用注解
定义说明书的显示方法1.@WebService(serviceName="PojoService", portName="PojoPort", name=&qu ...
- OpenStack之五: image镜像服务(端口9292)
官网地址:https://docs.openstack.org/glance/stein/install/install-rdo.html #:创建glance库,并授权 MariaDB [(none ...
- 3.3 rust HashMap
The type HashMap<K, V> stores a mapping of keys of type K to values of type V. It does this vi ...
- my42_Mysql基于ROW格式的主从同步
模拟主从update事务,从库跳过部分update事务后,再次开始同步的现象 主库 mysql> select * from dbamngdb.isNodeOK; +----+--------- ...
- springmvc中如何自定义类型转换器
package com.hope.utils;import org.springframework.core.convert.converter.Converter;import org.spring ...