61
61
62
62
<!-- 这里可写通用的实现逻辑 -->
63
63
64
- 先遍历左右子树,获得硬币的余额。比如,我们从左子树得到 ` left = "+3" ` ,说明左子树有 3 个额外的硬币需要移出。如果我们从右子树得到 ` right = "-1" ` ,说明右子树需要额外移入 1 个硬币。累加移动的次数 ` abs(+3) + abs(-1) ` ,然后返回整个二叉树的余额 ` left + right + root.val - 1 ` 。
64
+ ** 方法一:DFS **
65
65
66
- 返回最终的移动次数即可。
66
+ 我们定义一个函数 $dfs(node)$,表示以 $node$ 为根节点的子树中,金币的超载量,即金币的数量减去节点数。如果 $dfs(node)$ 为正数,表示该子树中金币的数量多于节点数,需要将多余的金币移出该子树;如果 $dfs(node)$ 为负数,表示该子树中金币的数量少于节点数,需要将不足的金币移入该子树。
67
+
68
+ 在函数 $dfs(node)$ 中,我们首先遍历左右子树,获得左右子树的金币超载量 $left$ 和 $right$。那么当前移动的次数需要加上 $|left| + |right|$,即将左右子树中的金币移动到当前节点。然后,我们返回整个子树的金币超载量,即 $left + right + node.val - 1$。
69
+
70
+ 最后返回移动的次数即可。
71
+
72
+ 时间复杂度 $O(n)$,空间复杂度 $O(h)$。其中 $n$ 和 $h$ 分别是二叉树的节点数和高度。
67
73
68
74
<!-- tabs:start -->
69
75
79
85
# self.left = left
80
86
# self.right = right
81
87
class Solution :
82
- def distributeCoins (self , root : TreeNode) -> int :
88
+ def distributeCoins (self , root : Optional[ TreeNode] ) -> int :
83
89
def dfs (root ):
84
- nonlocal ans
85
90
if root is None :
86
91
return 0
87
92
left, right = dfs(root.left), dfs(root.right)
93
+ nonlocal ans
88
94
ans += abs (left) + abs (right)
89
95
return left + right + root.val - 1
90
96
@@ -114,11 +120,9 @@ class Solution:
114
120
* }
115
121
*/
116
122
class Solution {
117
-
118
123
private int ans;
119
124
120
125
public int distributeCoins (TreeNode root ) {
121
- ans = 0 ;
122
126
dfs(root);
123
127
return ans;
124
128
}
@@ -151,26 +155,26 @@ class Solution {
151
155
*/
152
156
class Solution {
153
157
public:
154
- int ans;
155
-
156
158
int distributeCoins(TreeNode* root) {
157
- ans = 0;
159
+ int ans = 0;
160
+ function<int(TreeNode* )> dfs = [ &] (TreeNode* root) -> int {
161
+ if (!root) {
162
+ return 0;
163
+ }
164
+ int left = dfs(root->left);
165
+ int right = dfs(root->right);
166
+ ans += abs(left) + abs(right);
167
+ return left + right + root->val - 1;
168
+ };
158
169
dfs(root);
159
170
return ans;
160
171
}
161
-
162
- int dfs (TreeNode* root) {
163
- if (!root) return 0;
164
- int left = dfs(root->left), right = dfs(root->right);
165
- ans += abs(left) + abs(right);
166
- return left + right + root->val - 1;
167
- }
168
172
};
169
173
```
170
174
171
- ### **C++ **
175
+ ### **Go **
172
176
173
- ```cpp
177
+ ```go
174
178
/**
175
179
* Definition for a binary tree node.
176
180
* type TreeNode struct {
@@ -179,9 +183,8 @@ public:
179
183
* Right *TreeNode
180
184
* }
181
185
*/
182
- func distributeCoins(root *TreeNode) int {
183
- ans := 0
184
- var dfs func(root *TreeNode) int
186
+ func distributeCoins(root *TreeNode) (ans int) {
187
+ var dfs func(*TreeNode) int
185
188
dfs = func(root *TreeNode) int {
186
189
if root == nil {
187
190
return 0
@@ -191,7 +194,7 @@ func distributeCoins(root *TreeNode) int {
191
194
return left + right + root.Val - 1
192
195
}
193
196
dfs(root)
194
- return ans
197
+ return
195
198
}
196
199
197
200
func abs(x int) int {
@@ -202,6 +205,39 @@ func abs(x int) int {
202
205
}
203
206
```
204
207
208
+ ### ** TypeScript**
209
+
210
+ ``` ts
211
+ /**
212
+ * Definition for a binary tree node.
213
+ * class TreeNode {
214
+ * val: number
215
+ * left: TreeNode | null
216
+ * right: TreeNode | null
217
+ * constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
218
+ * this.val = (val===undefined ? 0 : val)
219
+ * this.left = (left===undefined ? null : left)
220
+ * this.right = (right===undefined ? null : right)
221
+ * }
222
+ * }
223
+ */
224
+
225
+ function distributeCoins(root : TreeNode | null ): number {
226
+ let ans = 0 ;
227
+ const dfs = (root : TreeNode | null ) => {
228
+ if (! root ) {
229
+ return 0 ;
230
+ }
231
+ const left = dfs (root .left );
232
+ const right = dfs (root .right );
233
+ ans += Math .abs (left ) + Math .abs (right );
234
+ return left + right + root .val - 1 ;
235
+ };
236
+ dfs (root );
237
+ return ans ;
238
+ }
239
+ ```
240
+
205
241
### ** ...**
206
242
207
243
```
0 commit comments