目录
979. 在二叉树中分配硬币
题目描述:
实现代码与解析:
dfs(后序遍历)
原理思路:
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
实现代码与解析:
dfs(后序遍历)
class Solution {
public:
int res = 0;
int traversal(TreeNode* cur) // return 硬币数 - 节点数
{
if (cur == NULL) return 0;
// 左侧硬币数 - 左侧节点数 + 右侧硬币数 - 右侧节点数 + 当前节点硬币数 - 当前节点1
int diff = traversal(cur->left) + traversal(cur->right) + cur->val - 1;
res += abs(diff);
return diff;
}
int distributeCoins(TreeNode* root) {
traversal(root);
return res;
}
};
原理思路:
其实是一道思维题,我们不要从硬币的角度去看,而是从边的角度去思考。
当一个子树的硬币数大于结点数时,硬币一定会移出此子树,所以连接此子树的边一定会有硬币数 - 结点数 个硬币经过,同理,若小于,那么一定会有硬币移入。这样我们统计每一个边硬币经过的次数,相加起来,就是我们的结果。