classSolution {privaterecordNodeInfo(int nodeCount,int coinSum){};publicintdistributeCoins(TreeNode root) {int[] result =newint[1];dfs(root, result);return result[0]; }privateNodeInfodfs(TreeNode node,int[] result) {if (node ==null) {returnnewNodeInfo(0,0); }NodeInfo left =dfs(node.left, result);NodeInfo right =dfs(node.right, result); result[0] +=Math.abs(left.nodeCount-left.coinSum) +Math.abs(right.nodeCount-right.coinSum);returnnewNodeInfo(left.nodeCount+right.nodeCount+1,left.coinSum+right.coinSum+node.val); }}/***idea: total moves = abs(subtree node count - suntree coin sum)For each node, we record the information [# of nodes in the subtree (include itself), # of total coins in the subtree (include itself)]. Then we know that for a certain node, if there are more coins than nodes in the subtree, the node must "contribute" the redundant coins to its parent. Else, if there are more nodes than coins in the subtree, then the node must "take" some coins from the parent.Both of these two operations will create moves in the tree. And we just need to add the absolute value of the (# nodes - # coins) to the final result because the move can be "contribute" or "take". The time complexity is O(n) because we are just traversing the tree.ex: 3 0. 0NodeInfo(1, 0)result += 1;NodeInfo(2, 0)result += 2T: O(n)S: O(n) */
Latest
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode() {} * TreeNode(int val) { this.val = val; } * TreeNode(int val, TreeNode left, TreeNode right) { * this.val = val; * this.left = left; * this.right = right; * } * } */classSolution {publicintdistributeCoins(TreeNode root) {int[] result =newint[1];dfs(root, result);return result[0]; }privateintdfs(TreeNode node,int[] result) {if (node ==null) {return0; }int leftDiff =dfs(node.left, result);int rightDiff =dfs(node.right, result);int diff = leftDiff + rightDiff +node.val-1; result[0] +=Math.abs(diff);return diff; }}/***T: O(n)S: O(n)we can only calculate moves based on the edge (from subtree to parent), with POST order-> how many moves, moves = left_sub + right_sub + node.val - 1 (1 node count)2 -> left child has diff -1, -1 +4 -1 = 2 -> 2 moves 0 / \ 1 -> means 1 moves4 0/ -> so means -1, one move0. ex: this 0 needs 1 coin ((node.val - 1)) -> and left_sub (0) + right_sub(0) + (node.val - 1) = -1 (like borrow from parent 1 conis!)so result = Math.abs(-1) = 1;return this diff = -1 to upper rescursionthen in 4 /4/0left_sub (-1) + right_sub(0) + (node.val - 1) = -1 + 0 + 4 - 1 = 2so means this node will moves 2 to parent (1 coin already move to child (because left_sub is -1))(result += math.abs(2)), result = 3 0 / \2 0 -> then here left_sub (0) + right_sub(0) + (node.val - 1) = -1 (result += math.abs(-1)), result = 4 0 -> left_sub (2) + right_sub(-1) + (node.val - 1) = 2 - 1 + 0 - 1 = 0 -> so no moves!/ \2 -1 so result = 4 movesin ths way, we accumulate from buttom to top, so there is no missing moves!focus on distribute coins from buttom to top by diff(node val, node count and left_sub, right_sub) */