[路飞]在二叉树中分配硬币

61 阅读1分钟

记录 1 道算法题

在二叉树中分配硬币

979. 在二叉树中分配硬币 - 力扣(LeetCode)


要求:二叉树每个节点都有 1 到 n 枚硬币,通过移动硬币,使二叉树每一个节点都分配 1 枚硬币,求最小移动次数。比如:[0,3,0],输出:3。

每一枚硬币的流向有方向,但路径是一样的。无论是计算从上往下还是下往上,都算作移动次数 + 1。所以我们可以假设没有硬币的节点流出了 -x 个硬币。有硬币的节点也流出了 -x 个硬币。由于当流动到某个节点输出 0 的时候,就代表均衡,每一个节点都有一枚硬币。最后一直回溯到根节点就可以知道硬币流动的路径,每一条路径算 1 次就能得到最小移动次数。

没有硬币的节点算流出 -1。

使用后序遍历解决

完整代码如下:

    function distributeCoins(root) {
        let res = 0
        function f(node) {
            if (!node) return 0
            
            const l = f(node.left)
            const r = f(node.right)
            // 每次输出都作为移动了多少硬币,所以是绝对值
            res += Math.abs(l) + Math.abs(r)
            // 减去自身需要的 1 枚硬币,其他都作为流出
            return node.val + l + r - 1
        }
        f(root)
        return res
    }