【每日一题Day265】LC979在二叉树中分配硬币 | 树形dp

在二叉树中分配硬币【LC979】

给定一个有 N 个结点的二叉树的根结点 root,树中的每个结点上都对应有 node.val 枚硬币,并且总共有 N 枚硬币。

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

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

好巧妙 没想出来

  • 思路:

    • 移动的次数可以视为所有边经过的金币数的累加和,如果某子树的金币数目 c o i n s coins coins等于节点数目 n o d e s nodes nodes,那么不需要进行移动;否则,一定有硬币需要向上或者向下移动,该边经过的金币数目为 ∣ c o i n s − n o d e s ∣ |coins-nodes| coinsnodes
    • 故该问题可以用树形dp解决,dfs返回每颗子树的金币数目和节点数目,计算每条边经过的金币数,累加返回结果
  • 实现

    class Solution {
        private int ans;
    
        public int distributeCoins(TreeNode root) {
            dfs(root);
            return ans;
        }
    
        private int[] dfs(TreeNode node) {
            if (node == null)
                return new int[]{0, 0};
            var left = dfs(node.left);
            var right = dfs(node.right);
            int coins = left[0] + right[0] + node.val; // 子树硬币个数
            int nodes = left[1] + right[1] + 1; // 子树节点数
            ans += Math.abs(coins - nodes);
            return new int[]{coins, nodes};
        }
    }
    
    作者:灵茶山艾府
    链接:https://leetcode.cn/problems/distribute-coins-in-binary-tree/solutions/2343262/tu-jie-mei-you-si-lu-jin-lai-miao-dong-p-vrni/
    来源:力扣(LeetCode)
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    
    • 复杂度
      • 时间复杂度: O ( n ) \mathcal{O}(n) O(n)
      • 空间复杂度: O ( n ) \mathcal{O}(n) O(n)
  • 优化:

    整理可得:
    d = c o i n s − n o d e s = ( c o i n s l e f t + c o i n s r i g h t + n o d e . v a l ) − ( n o d e s l e f t + n o d e s r i g h t + 1 ) = ( c o i n s l e f t − n o d e s l e f t ) + ( c o i n s r i g h t − n o d e s r i g h t ) + + n o d e . v a l − 1 = d l e f t + d r i g h t + n o d e . v a l − 1 d=coins−nodes\\ = (coins_{left}+coins_{right}+node.val)−(nodes_{left}+nodes_{right}+1)\\ =(coins_{left}-nodes_{left})+(coins_{right}-nodes_{right})++node.val-1\\ =d_{left}+d_{right} +node.val−1 d=coinsnodes=(coinsleft+coinsright+node.val)(nodesleft+nodesright+1)=(coinsleftnodesleft)+(coinsrightnodesright)++node.val1=dleft+dright+node.val1

    class Solution {
        private int ans;
    
        public int distributeCoins(TreeNode root) {
            dfs(root);
            return ans;
        }
    
        private int dfs(TreeNode node) {
            if (node == null)
                return 0;
            int d = dfs(node.left) + dfs(node.right) + node.val - 1;
            ans += Math.abs(d);
            return d;
        }
    }
    
    作者:灵茶山艾府
    链接:https://leetcode.cn/problems/distribute-coins-in-binary-tree/solutions/2343262/tu-jie-mei-you-si-lu-jin-lai-miao-dong-p-vrni/
    来源:力扣(LeetCode)
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    
    • 复杂度
      • 时间复杂度: O ( n ) \mathcal{O}(n) O(n)
      • 空间复杂度: O ( n ) \mathcal{O}(n) O(n)

你可能感兴趣的:(每日一题,动态规划,leetcode,动态规划)