问题: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 = ;
if (root == NULL)
{
return ;
}
else
{
int tmpleftnodes = ;
int tmpleftconins = ;
int tmprightnodes = ;
int tmprightcoins = ;
int tmpselfnode = ;
int tmpselfcoins = ;
GetInfo(root, tmpleftnodes, tmpleftconins, tmprightnodes, tmprightcoins, tmpselfnode, tmpselfcoins); int tmpdeltaleft = tmpleftconins - tmpleftnodes;
int tmpdeltaright = tmprightcoins - tmprightnodes;
//int tmpselfdelta = tmpselfcoins - tmpselfnode;
int tmpselfdelta = ;
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 = ;
leftconins = ;
rightnodes = ;
rightcoins = ;
selfnode = ;
selfcoins = ;
return;
}
else if (root->left == NULL && root->right == NULL)
{
leftnodes = ;
leftconins = ;
rightnodes = ;
rightcoins = ;
selfnode = ;
selfcoins = root->val;
return;
}
else //if (root->left != NULL && root->right != NULL)
{
int tmpleftnodes = ;
int tmpleftconins = ;
int tmprightnodes = ;
int tmprightcoins = ;
int tmpselfnode = ;
int tmpselfcoins = ;
GetInfo(root->left, tmpleftnodes, tmpleftconins, tmprightnodes, tmprightcoins, tmpselfnode, tmpselfcoins);
leftnodes = tmpleftnodes + tmprightnodes + tmpselfnode;
leftconins = tmpleftconins + tmprightcoins + tmpselfcoins; tmpleftnodes = ;
tmpleftconins = ;
tmprightnodes = ;
tmprightcoins = ;
tmpselfnode = ;
tmpselfcoins = ;
GetInfo(root->right, tmpleftnodes, tmpleftconins, tmprightnodes, tmprightcoins, tmpselfnode, tmpselfcoins);
rightnodes = tmpleftnodes + tmprightnodes + tmpselfnode;
rightcoins = tmpleftconins + tmprightcoins + tmpselfcoins;
selfnode = ;
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={,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=;
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 ;
return + sz(root->left) + sz(root->right);
} int coins(TreeNode* root) {
if (root == nullptr) {
return ;
} 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 subtree
if (root == nullptr) {
return ;
}
return abs(coins(root) - sz(root)) + distributeCoins(root->left) + distributeCoins(root->right);
}
};

LeetCode979. 在二叉树中分配硬币的更多相关文章

  1. [Swift]LeetCode979. 在二叉树中分配硬币 | 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 ...

  2. Leetcode979 : Distribute Coins in Binary Tree 二叉树均匀分配硬币问题

    问题 给定一个二叉树的root节点,二叉树中每个节点有node.val个coins,一种有N coins. 现在要求移动节点中的coins 使得二叉树最终每个节点的coins value都为1.每次移 ...

  3. C语言实现二叉树中统计叶子结点的个数&度为1&度为2的结点个数

    算法思想 统计二叉树中叶子结点的个数和度为1.度为2的结点个数,因此可以参照二叉树三种遍历算法(先序.中序.后序)中的任何一种去完成,只需将访问操作具体变为判断是否为叶子结点和度为1.度为2的结点及统 ...

  4. python3实现在二叉树中找出和为某一值的所有路径

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

  5. 在Quartus II中分配管脚的两种常用方法

    在Quartus II中分配管脚的两种常用方法 示范程序 seg7_test.v 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 /* * ...

  6. IT公司100题-11-求二叉树中节点的最大距离

    问题描述: 写程序,求一棵二叉树中相距最远的两个节点之间的距离. 10/     \6      14/   \   /   \4    8 12    16 分析: 二叉树中最远的两个节点,要么是根 ...

  7. 动态链接库中分配内存引起的问题-- windows已在XX.exe中触发一个断点

    动态链接库中分配内存引起的 本文主要是探讨关于在动态链接库分配的内存在主程序中释放所产生的问题,该问题是我在刚做的PJP工程中所遇到的,由于刚碰到之时感动比较诡异(这也是学识不够所致),所以将它写下来 ...

  8. 二叉树中序遍历 (C语言实现)

    在计算机科学中,树是一种重要的非线性数据结构,直观地看,它是数据元素(在树中称为结点)按分支关系组织起来的结构.二叉树是每个节点最多有两个子树的有序树.通常子树被称作“左子树”(left subtre ...

  9. 94 Binary Tree Inorder Traversal(二叉树中序遍历Medium)

    题目意思:二叉树中序遍历,结果存在vector<int>中 解题思路:迭代 迭代实现: /** * Definition for a binary tree node. * struct ...

随机推荐

  1. MySQL中报错: [Err] 1146 - Table 'performance_schema.session_status' doesn't exist 解决办法

    解决办法:1.打开cmd 执行命令cd/ 进入C盘根目录2.dir 查看C盘根目录下文件夹  找到 Program Files文件夹3.cd Program Files 进入该文件夹下 再输入dir ...

  2. .net core 共享 .Net Forms Authentication cookie

    Asp.net 项目迁移到 asp.net core 项目后需要 兼容以前老的项目的登录方式. Forms Authentication cookie 登录. 从网上搜集到关于这个问题的解决思路都没有 ...

  3. #CSS的盒子模型、元素类型

    CSS的盒子模型.元素类型   本文首先介绍了CSS元素的统一内部结构模型,盒子模型:然后介绍了CSS元素基于不同分类标准定义的元素类型,包括基于不同内容设置方式定义的replaced元素和non-r ...

  4. Brackets - 前端神器

    做了几年的 .Net 项目开发,后来公司转 Java 语言开发,Java 做了还没一年,公司准备前后端分离开发,而我被分到前端! Brackets是一款基于web(html+css+js)开发的web ...

  5. Android修改AlertDialog宽和高以及设置AlertDialog的背景

    不知道你们试过了吗,AlertDialog在我们给他设置我们自己的布局的时候他的宽度不论我们怎么设置他都是不变的,要想改变宽和高我们可以动态的去修改他的宽度好高度 直接上代码 // 1. 布局文件转换 ...

  6. Android 编码风格规范,很赞哦

    1. 前言 这份文档参考了 Google Java 编程风格规范和 Google 官方 Android 编码风格规范.该文档仅供参考,只要形成一个统一的风格,见量知其意就可. 1.1 术语说明 在本文 ...

  7. android listview 加载遇到的问题

    http://blog.csdn.net/l_serein/article/details/7706338 转载: 描述一下场景: 菜单栏上有若干分类,点击每一个分类,ListView下分根据分类显示 ...

  8. Javascript基础--函数(Function对象)

    1.函数是一段可执行的代码,函数可多次调用,模块化管理. 2.使用function语句,function funName([arg1][,arg2]....[,argn]){代码块}.所有版本可用,一 ...

  9. Azure资源模板化部署,伦家不懒都不好意思了

    如果老板让你在云平台上部署一套系统,你准备怎么做? 嗯,估计得根据具体需求开通或创建一大堆东西:虚拟机.存储.数据库.虚拟网络……别急还没完,接着还要对这些东西的规模.配置等各方面调整和优化.一系列环 ...

  10. Linux远程桌面管理

    一: (1)查看用户  Linux系统root用户可强制踢制其它登录用户,首先可用w命令查看登录用户信息 [root@ylLinux~]:# w (2)强制踢人 命令格式:pkill -kill -t ...