zoukankan      html  css  js  c++  java
  • [LeetCode] 979. Distribute Coins in Binary Tree

    Given the root of a binary tree with N nodes, each node in the tree has node.val coins, and there are N coins total.

    In one move, we may choose two adjacent nodes and move one coin from one node to another.  (The move may be from parent to child, or from child to parent.)

    Return the number of moves required to make every node have exactly one coin.

    Example 1:

    Input: [3,0,0]
    Output: 2
    Explanation: From the root of the tree, we move one coin to its left child, 
    and one coin to its right child.

    Example 2:

    Input: [0,3,0]
    Output: 3
    Explanation: From the left child of the root, we move two coins to 
    the root [taking two moves].
    Then, we move one coin from the root of the tree to the right child.

    Example 3:

    Input: [1,0,2]
    Output: 2
    

    Example 4:

    Input: [1,0,0,null,3]
    Output: 4

    Note:

    1. 1<= N <= 100
    2. 0 <= node.val <= N

    在二叉树中分配硬币。给定一个有N个节点的二叉树,树中每个节点都有若干硬币,树中硬币的总数是N。现在需要将硬币作适当移动,确保树中的每个节点都有一个硬币。请返回最少的操作次数,保证树中的每个节点都有一个硬币。

    思路是DFS后序遍历。对于每一个没有硬币的节点来说,他们需要向有硬币的节点“求救”,告诉有硬币的节点你需要给我一个硬币。比如第一个例子,现在有一个包含三个节点的树,其中三个硬币都在根节点上,那么两个孩子节点就需要想个办法告诉根节点我们各自需要一个硬币来满足条件。

    对于两个孩子节点,他们往根节点传一个我需要一个硬币的值这么一个信息。其实从移动次数上,是等同于从根节点分别往两个孩子节点传一个硬币的。所以我们用后序遍历的方式,从孩子节点往根节点遍历,遍历的时候累加所需要的硬币个数的和。最后dfs函数输出的就是所有孩子节点需要从根节点拿的硬币数量。如果某个孩子节点已经有一个硬币了,他传的硬币个数自然是0;如果某个孩子节点有多个硬币,他传的硬币个数 = node.val - 1,因为他只需要保留一个硬币即可。注意往根节点传这个参数的时候需要取绝对值。

    时间O(n)

    空间O(n)

    Java实现

     1 /**
     2  * Definition for a binary tree node.
     3  * public class TreeNode {
     4  *     int val;
     5  *     TreeNode left;
     6  *     TreeNode right;
     7  *     TreeNode() {}
     8  *     TreeNode(int val) { this.val = val; }
     9  *     TreeNode(int val, TreeNode left, TreeNode right) {
    10  *         this.val = val;
    11  *         this.left = left;
    12  *         this.right = right;
    13  *     }
    14  * }
    15  */
    16 class Solution {
    17     int res = 0;
    18     
    19     public int distributeCoins(TreeNode root) {
    20         // corner case
    21         if (root == null) {
    22             return 0;
    23         }
    24         helper(root);
    25         return res;
    26     }
    27     
    28     private int helper(TreeNode root) {
    29         if (root == null) {
    30             return 0;
    31         }
    32         int left = helper(root.left);
    33         int right = helper(root.right);
    34         res += Math.abs(left) + Math.abs(right);
    35         return root.val + left + right - 1;
    36     }
    37 }

    LeetCode 题目总结

  • 相关阅读:
    Bash : 冒泡排序
    Azure Load Balancer : 支持 IPv6
    Azure Load Balancer : 简介
    sudo 与输出重定向
    Linux lsof 命令
    Bash : IO 重定向
    LVM : 快照
    2014年全年总结
    使用Kindle4rss推送自己感兴趣的博文
    换SSD硬盘,重装系统,一阵子忙乱
  • 原文地址:https://www.cnblogs.com/cnoodle/p/13712255.html
Copyright © 2011-2022 走看看