二叉树题目:在二叉树中分配硬币

题目

标题和出处

标题:在二叉树中分配硬币

出处:979. 在二叉树中分配硬币

难度

6 级

题目描述

要求

给定一个有 n \texttt{n} n 个结点的二叉树的根结点 root \texttt{root} root,树中的每个结点 node \texttt{node} node 上有 node.val \texttt{node.val} node.val 枚硬币。整个树中总共有 n \texttt{n} n 枚硬币。

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

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

示例

示例 1:

示例 1

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

示例 2:

示例 2

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

数据范围

  • 树中结点数目是 n \texttt{n} n
  • 1 ≤ n ≤ 100 \texttt{1} \le \texttt{n} \le \texttt{100} 1n100
  • 0 ≤ Node.val ≤ n \texttt{0} \le \texttt{Node.val} \le \texttt{n} 0Node.valn
  • 所有的 Node.val \texttt{Node.val} Node.val 之和是 n \texttt{n} n

解法

思路和算法

为了计算平均分配硬币的最少移动次数,需要计算每个子树中的硬币数与结点数的差值。差值等于 0 0 0 表示子树中的硬币树等于结点数;差值大于 0 0 0 表示子树中的硬币数大于结点数,需要将多余的硬币移动到当前子树根结点的父结点;差值小于 0 0 0 表示子树中的硬币数小于结点数,需要将缺少的硬币从当前子树根结点的父结点移动到当前子树。在计算每个子树中的硬币数与结点数的差值时,同步计算移动次数。

如果二叉树为空,则差值为 0 0 0。如果二叉树不为空,则差值为的左子树的差值、右子树的差值与根结点的差值之和,其中左子树的差值与右子树的差值是规模更小的问题,可以使用同样的方法计算,根结点的差值等于根结点值减 1 1 1,即根结点的硬币数与目标硬币数(目标硬币数为 1 1 1)之差。得到左子树的差值与右子树的差值之后即可更新移动次数。对于每个子树,如果差值为 x x x,则当 x > 0 x > 0 x>0 时需要将 ∣ x ∣ |x| x 个硬币从该子树移动到根结点,当 x < 0 x < 0 x<0 时需要将 ∣ x ∣ |x| x 个硬币从根结点移动到该子树,因此需要 ∣ x ∣ |x| x 次移动。

计算二叉树的差值可以使用深度优先搜索实现。整个过程是一个递归的过程,递归的终止条件是当前子树为空,此时差值为 0 0 0。其余情况下,首先计算左子树和右子树的差值,然后计算当前子树的差值并更新移动次数。

遍历结束之后即可得到平均分配硬币的最少移动次数。由于上述计算过程中,移动次数等于需要移动的硬币数,因此可以确保得到的移动次数是最少的。

代码

class Solution {
    int moves = 0;

    public int distributeCoins(TreeNode root) {
        count(root);
        return moves;
    }

    public int count(TreeNode node) {
        if (node == null) {
            return 0;
        }
        int countLeft = count(node.left);
        int countRight = count(node.right);
        moves += Math.abs(countLeft) + Math.abs(countRight);
        return countLeft + countRight + node.val - 1;
    }
}

复杂度分析

  • 时间复杂度: O ( n ) O(n) O(n),其中 n n n 是二叉树的结点数。每个结点都被访问一次。

  • 空间复杂度: O ( n ) O(n) O(n),其中 n n n 是二叉树的结点数。空间复杂度主要是递归调用的栈空间,取决于二叉树的高度,最坏情况下是 O ( n ) O(n) O(n)

  • 17
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

伟大的车尔尼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值