2023-07-14每日一题
一、题目编号
979. 在二叉树中分配硬币
二、题目链接
三、题目描述
给定一个有 N 个结点的二叉树的根结点 root,树中的每个结点上都对应有 node.val 枚硬币,并且总共有 N 枚硬币。
在一次移动中,我们可以选择两个相邻的结点,然后将一枚硬币从其中一个结点移动到另一个结点。(移动可以是从父结点到子结点,或者从子结点移动到父结点。)。
返回使每个结点上只有一枚硬币所需的移动次数。
提示:
- 1<= N <= 100
- 0 <= node.val <= N
四、解题代码
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int res = 0;
int dfs(TreeNode* root){
if(root == nullptr){
return 0;
}
int move_left = 0; // 硬币在左子树所需要移动的个数
int move_right = 0; // 硬币在右子树所需要移动的个数
if(root->left){
move_left = dfs(root->left);
}
if(root->right){
move_right = dfs(root->right);
}
res += abs(move_left) + abs(move_right);
return move_left + move_right + root->val - 1;
}
int distributeCoins(TreeNode* root) {
dfs(root);
return res;
}
};
五、解题思路
(1) 首先我们思考一个问题,如果在一棵树中如何移动硬币。
(2) 最简单的思考方式就是一棵树,左边有硬币移动,右边也有硬币移动,那么需要移动的个数就是左边的硬币移动次数+右边的硬币移动次数。
(3) 但是问题就是。比如说现在有一个三个结点的子树(左右各两个节点),左子树有3枚硬币,右子树没有硬币,根也没有。那么左子树需要移动硬币次数就为硬币个数3 - 1即可。右子树的移动个数立为0 - 1的绝对值等于1。又由于该两个左右节点子树并不需要硬币,所以,递归的时候,左右移动的个数即为0。实际递归的时候需要加上。
(4) 最后返回结果即可。