问题:979. 在二叉树中分配硬币

给定一个有 N 个结点的二叉树的根结点 root,树中的每个结点上都对应有 node.val 枚硬币,并且总共有 N 枚硬币。

在一次移动中,我们可以选择两个相邻的结点,然后将一枚硬币从其中一个结点移动到另一个结点。(移动可以是从父结点到子结点,或者从子结点移动到父结点。)。

返回使每个结点上只有一枚硬币所需的移动次数。

示例 1:

输入:[3,0,0]
输出:2
解释:从树的根结点开始,我们将一枚硬币移到它的左子结点上,一枚硬币移到它的右子结点上。

示例 2:

输入:[0,3,0]
输出:3
解释:从根结点的左子结点开始,我们将两枚硬币移到根结点上 [移动两次]。然后,我们把一枚硬币从根结点移到右子结点上。

示例 3:

输入:[1,0,2]
输出:2

示例 4:

输入:[1,0,0,null,3]
输出:4

提示:

  1. 1<= N <= 100
  2. 0 <= node.val <= N

链接:https://leetcode-cn.com/contest/weekly-contest-120/problems/distribute-coins-in-binary-tree/

分析:

0.每个节点硬币存在如下几种流向:给父节点、给左子节点、给右子节点;

1.将左右节点看做一个整体,向上和向下流向是对称的,只需要统计一个方向的即可,而且左右节点看做一个整体,分发后在分别内部递归进行后续分发;

2.如果某个节点为空,则流动次数为0;

3.如果某个节点不为空,左节点节点数Node1,硬币数Coins1,右节点数Node2,硬币数Coins2,由于节点数和硬币数一致,所以差值的绝对值即需要的流动次数,即父节点给左节点的X个硬币加上父节点给右节点的Y个硬币是这一层的流动次数

4.分别计算左右节点的移动次数,累加即为结果。

AC Code:

/*** 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 ret = 0;if (root == NULL){return 0;}else{int tmpleftnodes = 0;int tmpleftconins = 0;int tmprightnodes = 0;int tmprightcoins = 0;int tmpselfnode = 0;int tmpselfcoins = 0;GetInfo(root, tmpleftnodes, tmpleftconins, tmprightnodes, tmprightcoins, tmpselfnode, tmpselfcoins);int tmpdeltaleft = tmpleftconins - tmpleftnodes;int tmpdeltaright = tmprightcoins - tmprightnodes;//int tmpselfdelta = tmpselfcoins - tmpselfnode;int tmpselfdelta = 0;ret = ret + abs(tmpselfdelta - tmpdeltaleft) + abs(tmpselfdelta - tmpdeltaright);ret = ret + distributeCoins(root->left) + distributeCoins(root->right);}return ret;}//获得该节点左右节点数以及所拥有的硬币数void GetInfo(TreeNode* root, int& leftnodes, int& leftconins, int& rightnodes, int& rightcoins,int& selfnode,int& selfcoins){if (root == NULL){leftnodes = 0;leftconins = 0;rightnodes = 0;rightcoins = 0;selfnode = 0;selfcoins = 0;return;}else if (root->left == NULL && root->right == NULL){leftnodes = 0;leftconins = 0;rightnodes = 0;rightcoins = 0;selfnode = 1;selfcoins = root->val;return;            }else //if (root->left != NULL && root->right != NULL)
        {int tmpleftnodes = 0;int tmpleftconins = 0;int tmprightnodes = 0;int tmprightcoins = 0;int tmpselfnode = 0;int tmpselfcoins = 0;GetInfo(root->left, tmpleftnodes, tmpleftconins, tmprightnodes, tmprightcoins, tmpselfnode, tmpselfcoins);leftnodes = tmpleftnodes + tmprightnodes + tmpselfnode;leftconins = tmpleftconins + tmprightcoins + tmpselfcoins;tmpleftnodes = 0;tmpleftconins = 0;tmprightnodes = 0;tmprightcoins = 0;tmpselfnode = 0;tmpselfcoins = 0;GetInfo(root->right, tmpleftnodes, tmpleftconins, tmprightnodes, tmprightcoins, tmpselfnode, tmpselfcoins);rightnodes = tmpleftnodes + tmprightnodes + tmpselfnode;rightcoins = tmpleftconins + tmprightcoins + tmpselfcoins;selfnode = 1;selfcoins = root->val;}}};

其他:

1.由于左右均衡是通过父节点实现的,所以其实不需要看父节点的硬币数量

2.第一code:

typedef signed long long ll;#undef _P
#define _P(...) (void)printf(__VA_ARGS__)
#define FOR(x,to) for(x=0;x<(to);x++)
#define FORR(x,arr) for(auto& x:arr)
#define ITR(x,c) for(__typeof(c.begin()) x=c.begin();x!=c.end();x++)
#define ALL(a) (a.begin()),(a.end())
#define ZERO(a) memset(a,0,sizeof(a))
#define MINUS(a) memset(a,0xff,sizeof(a))
//-------------------------------------------------------class Solution {
public:int ret;pair<int,int> count(TreeNode* root) {pair<int,int> A={1,root->val};if(root->left) {auto a=count(root->left);A.first+=a.first;A.second+=a.second;}if(root->right) {auto a=count(root->right);A.first+=a.first;A.second+=a.second;}ret+=abs(A.first-A.second);return A;}int distributeCoins(TreeNode* root) {ret=0;count(root);return ret;}
};

pair记录节点个数和所拥有的硬币数,差值都是需要流动的

另一个code:

/*** 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 sgn(int x) {if (x == 0)return 0;return x < 0 ? -1 : 1;}int maxTurbulenceSize(vector<int>& A) {int n = A.size();int l = 0;int ans = 1;for (int r = 1; r < n; ++r) {if (l + 1 < r and sgn(a[r] - a[r - 1]) == sgn(a[r - 1] - a[r - 2])) {l = r - 1;}if (a[r] == a[r - 1]) {l = r;}ans = max(ans, r - l + 1);}return ans;}
};*/class Solution {
public:int sz(TreeNode* root) {if (root == nullptr)return 0;return 1 + sz(root->left) + sz(root->right);}int coins(TreeNode* root) {if (root == nullptr) {return 0;}return root->val + coins(root->left) + coins(root->right);}int distributeCoins(TreeNode* root) {// number of coins over edge = diff between coins and nodes for each subtreeif (root == nullptr) {return 0;}return abs(coins(root) - sz(root)) + distributeCoins(root->left) + distributeCoins(root->right);}
};

转载于:https://www.cnblogs.com/youdias/p/10294514.html

LeetCode979. 在二叉树中分配硬币相关推荐

  1. leetcode979. 在二叉树中分配硬币(dfs)

    给定一个有 N 个结点的二叉树的根结点 root,树中的每个结点上都对应有 node.val 枚硬币,并且总共有 N 枚硬币. 在一次移动中,我们可以选择两个相邻的结点,然后将一枚硬币从其中一个结点移 ...

  2. LeetCode 979. 在二叉树中分配硬币(DFS)

    文章目录 1. 题目 2. DFS 解题 1. 题目 给定一个有 N 个结点的二叉树的根结点 root,树中的每个结点上都对应有 node.val 枚硬币,并且总共有 N 枚硬币. 在一次移动中,我们 ...

  3. leetcode —— 979. 在二叉树中分配硬币

    给定一个有 N 个结点的二叉树的根结点 root,树中的每个结点上都对应有 node.val 枚硬币,并且总共有 N 枚硬币. 在一次移动中,我们可以选择两个相邻的结点,然后将一枚硬币从其中一个结点移 ...

  4. 二叉树路径和最大python_python3实现在二叉树中找出和为某一值的所有路径(推荐)...

    请写一个程序创建一棵二叉树,并按照一定规则,输出二叉树根节点到叶子节点的路径. 规则如下: 1.从最顶端的根结点,到最下面的叶子节点,计算路径通过的所有节点的和,如果与设置的某一值的相同,那么输出这条 ...

  5. (c语言)二叉树中序线索(数据结构十七)

    1.数据类型定义 在代码中为了清楚的表示一些错误和函数运行状态,我们预先定义一些变量来表示这些状态.在head.h头文件中有如下定义: //定义数据结构中要用到的一些变量和类型 #ifndef HEA ...

  6. 计算机里面哪个代表度,二叉树中的度是什么?

    二叉树是一种很重要的非线性数据结构,它的特点是每个结点最多有两个后件,且其子树有左右之分(次序不能任意颠倒). 1.二叉树的递归定义和基本形态 二叉树是以结点为元素的有限集,它或者为空,或者满足以下条 ...

  7. 非递归,不用栈实现二叉树中序遍历

    最近总有人问这个问题:"如何不用栈,也不用递归来实现二叉树的中序遍历".这个问题的实现就是迭代器问题,无论是Java还是C++,利用迭代器遍历树节点(Java中是TreeMap类, ...

  8. 微软算法100题11 求二叉树中两节点之间的最大距离

    第11 题 求二叉树中节点的最大距离... 如果我们把二叉树看成一个图,父子节点之间的连线看成是双向的, 我们姑且定义"距离"为两节点之间边的个数. 写一个程序, 求一棵二叉树中相 ...

  9. 【每日一算法】二叉树中所有距离为 K 的结点

    微信改版,加星标不迷路! 每日一算法-二叉树中所有距离为K的节点 给定一个二叉树(具有根结点 root), 一个目标结点 target ,和一个整数值 K . 返回到目标结点 target 距离为 K ...

最新文章

  1. 计算机论文工作进程记录,毕业设计进程记录
  2. 在线qmc0转换mp3工具_如何将M4A格式的音频转换为MP3格式?只需一步搞定
  3. Java静态初始化,实例初始化以及构造方法
  4. 【吐血整理】java正则表达式详解
  5. 学计算机需要用手机吗,智能手机能代替电脑吗?
  6. EXCEL小技巧:如何统计非空单元格
  7. GWT的渐进式Web应用程序配方
  8. python 内置方法赋值_Python内置数据结构之字符串str
  9. Mybatis中接口和对应的mapper文件位置配置详解
  10. Python日志模块学习,从这里开始...
  11. 如何用Html+css3写一个简单的网页
  12. java 获取文件所在的文件夹_带你0基础编写一个Java小程序,领略Java程序从编写到编译再到运行的全流程...
  13. 截止11月5日,30日内累计跌幅最大的200只股票
  14. cacti 监控自身
  15. 联想拯救者Y7000P win10+ubuntu20.04 双系统安装
  16. php工程师绩效考核表_如何对程序员绩效考核?
  17. tooltips使用教程(鼠标悬停时显示提示)
  18. 2022 年前面试总结与感悟分享
  19. db2的驱动程序为db2jcc4-1.6.0_97.jar和db2jcc_license_cu-1.4.2_9.7.jar
  20. 手机android app 无线控制led灯开关

热门文章

  1. excel表头_「Excel技巧」关于Excel表格打印常见的四个问题,你会解决吗?
  2. java 读取 jar properties_java:如何读取properties文件内容
  3. CYQ.Data 轻量数据层之路 使用篇-MAction 数据查询 视频 D (二十一)
  4. django项目实现第三方github登录
  5. 日志服务Python消费组实战(三):实时跨域监测多日志库数据
  6. 《Oracle高性能自动化运维》一一2.3 Library Cache
  7. 非官方构建的 Windows 下的 Atom 编辑器
  8. #include,#import ,@class 有什么区别?
  9. 你的袜子还是干的吗?
  10. Dreamweaver格式化html代码提高代码质量