51
51
52
52
<!-- 这里可写通用的实现逻辑 -->
53
53
54
- 朴素解法是直接遍历整棵完全二叉树,统计结点个数。时间复杂度 $O(n)$。
54
+ ** 方法一:递归**
55
+
56
+ 递归遍历整棵树,统计结点个数。
57
+
58
+ 时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为树的结点个数。
59
+
60
+ ** 方法二:二分查找**
55
61
56
62
对于此题,我们还可以利用完全二叉树的特点,设计一个更快的算法。
57
63
58
64
完全二叉树的特点:叶子结点只能出现在最下层和次下层,且最下层的叶子结点集中在树的左部。需要注意的是,满二叉树肯定是完全二叉树,而完全二叉树不一定是满二叉树。
59
65
60
- 若满二叉树的层数为 h ,则总结点数为 ` 2^h - 1 ` 。
66
+ 若满二叉树的层数为 $h$ ,则总结点数为 $ 2^h - 1$ 。
61
67
62
- 我们可以先对 root 的左右子树进行高度统计,分别记为 left, right。
68
+ 我们可以先对 $ root$ 的左右子树进行高度统计,分别记为 $ left$ 和 $ right$ 。
63
69
64
- 1 . 若 ` left == right ` ,说明左子树是一颗满二叉树。所以左子树的结点总数为 ` 2^ left - 1` ,加上 root 结点,就是 ` 2^ left` ,然后递归统计右子树即可。
65
- 1 . 若 ` left > right ` ,说明右子树是一个满二叉树。所以右子树的结点总数为 ` 2^ right - 1` ,加上 root 结点,就是 ` 2^ right` ,然后递归统计左子树即可。
70
+ 1 . 若 $ left = right$ ,说明左子树是一颗满二叉树,那么左子树的结点总数为 $2^{ left} - 1$ ,加上 $ root$ 结点,就是 $2^{ left}$ ,然后递归统计右子树即可。
71
+ 1 . 若 $ left > right$ ,说明右子树是一个满二叉树,那么右子树的结点总数为 $2^{ right} - 1$ ,加上 $ root$ 结点,就是 $2^{ right}$ ,然后递归统计左子树即可。
66
72
67
73
时间复杂度 $O(\log^2 n)$。
68
74
80
86
# self.left = left
81
87
# self.right = right
82
88
class Solution :
83
- def countNodes (self , root : TreeNode) -> int :
89
+ def countNodes (self , root : Optional[TreeNode]) -> int :
90
+ if root is None :
91
+ return 0
92
+ return 1 + self .countNodes(root.left) + self .countNodes(root.right)
93
+ ```
94
+
95
+ ``` python
96
+ # Definition for a binary tree node.
97
+ # class TreeNode:
98
+ # def __init__(self, val=0, left=None, right=None):
99
+ # self.val = val
100
+ # self.left = left
101
+ # self.right = right
102
+ class Solution :
103
+ def countNodes (self , root : Optional[TreeNode]) -> int :
84
104
def depth (root ):
85
- res = 0
105
+ d = 0
86
106
while root:
87
- res += 1
107
+ d += 1
88
108
root = root.left
89
- return res
90
-
109
+ return d
110
+
91
111
if root is None :
92
112
return 0
93
113
left, right = depth(root.left), depth(root.right)
@@ -100,6 +120,32 @@ class Solution:
100
120
101
121
<!-- 这里可写当前语言的特殊实现逻辑 -->
102
122
123
+ ``` java
124
+ /**
125
+ * Definition for a binary tree node.
126
+ * public class TreeNode {
127
+ * int val;
128
+ * TreeNode left;
129
+ * TreeNode right;
130
+ * TreeNode() {}
131
+ * TreeNode(int val) { this.val = val; }
132
+ * TreeNode(int val, TreeNode left, TreeNode right) {
133
+ * this.val = val;
134
+ * this.left = left;
135
+ * this.right = right;
136
+ * }
137
+ * }
138
+ */
139
+ class Solution {
140
+ public int countNodes (TreeNode root ) {
141
+ if (root == null ) {
142
+ return 0 ;
143
+ }
144
+ return 1 + countNodes(root. left) + countNodes(root. right);
145
+ }
146
+ }
147
+ ```
148
+
103
149
``` java
104
150
/**
105
151
* Definition for a binary tree node.
@@ -130,10 +176,11 @@ class Solution {
130
176
}
131
177
132
178
private int depth (TreeNode root ) {
133
- int res = 0 ;
134
- for (; root != null ; root = root. left, ++ res)
135
- ;
136
- return res;
179
+ int d = 0 ;
180
+ for (; root != null ; root = root. left) {
181
+ ++ d;
182
+ }
183
+ return d;
137
184
}
138
185
}
139
186
```
@@ -155,18 +202,46 @@ class Solution {
155
202
class Solution {
156
203
public:
157
204
int countNodes(TreeNode* root) {
158
- if (!root) return 0;
205
+ if (!root) {
206
+ return 0;
207
+ }
208
+ return 1 + countNodes(root->left) + countNodes(root->right);
209
+ }
210
+ };
211
+ ```
212
+
213
+ ```cpp
214
+ /**
215
+ * Definition for a binary tree node.
216
+ * struct TreeNode {
217
+ * int val;
218
+ * TreeNode *left;
219
+ * TreeNode *right;
220
+ * TreeNode() : val(0), left(nullptr), right(nullptr) {}
221
+ * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
222
+ * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
223
+ * };
224
+ */
225
+ class Solution {
226
+ public:
227
+ int countNodes(TreeNode* root) {
228
+ if (!root) {
229
+ return 0;
230
+ }
159
231
int left = depth(root->left);
160
232
int right = depth(root->right);
161
- if (left == right) return (1 << left) + countNodes(root->right);
233
+ if (left == right) {
234
+ return (1 << left) + countNodes(root->right);
235
+ }
162
236
return (1 << right) + countNodes(root->left);
163
237
}
164
238
165
239
int depth(TreeNode* root) {
166
- int res = 0;
167
- for (; root != nullptr; ++res, root = root->left)
168
- ;
169
- return res;
240
+ int d = 0;
241
+ for (; root; root = root->left) {
242
+ ++d;
243
+ }
244
+ return d;
170
245
}
171
246
};
172
247
```
@@ -186,20 +261,36 @@ func countNodes(root *TreeNode) int {
186
261
if root == nil {
187
262
return 0
188
263
}
189
- depth := func (root *TreeNode) int {
190
- res := 0
191
- for root != nil {
192
- res++
193
- root = root.Left
194
- }
195
- return res
264
+ return 1 + countNodes (root.Left ) + countNodes (root.Right )
265
+ }
266
+ ```
267
+
268
+ ``` go
269
+ /* *
270
+ * Definition for a binary tree node.
271
+ * type TreeNode struct {
272
+ * Val int
273
+ * Left *TreeNode
274
+ * Right *TreeNode
275
+ * }
276
+ */
277
+ func countNodes (root *TreeNode ) int {
278
+ if root == nil {
279
+ return 0
196
280
}
197
281
left , right := depth (root.Left ), depth (root.Right )
198
282
if left == right {
199
283
return (1 << left) + countNodes (root.Right )
200
284
}
201
285
return (1 << right) + countNodes (root.Left )
202
286
}
287
+
288
+ func depth (root *TreeNode ) (d int ) {
289
+ for ; root != nil ; root = root.Left {
290
+ d++
291
+ }
292
+ return
293
+ }
203
294
```
204
295
205
296
### ** JavaScript**
@@ -218,12 +309,37 @@ func countNodes(root *TreeNode) int {
218
309
* @return {number}
219
310
*/
220
311
var countNodes = function (root ) {
221
- if (! root) return 0 ;
222
- let depth = function (root ) {
223
- let res = 0 ;
224
- for (; root != null ; ++ res, root = root .left );
225
- return res;
312
+ if (! root) {
313
+ return 0 ;
314
+ }
315
+ return 1 + countNodes (root .left ) + countNodes (root .right );
316
+ };
317
+ ```
318
+
319
+ ``` js
320
+ /**
321
+ * Definition for a binary tree node.
322
+ * function TreeNode(val, left, right) {
323
+ * this.val = (val===undefined ? 0 : val)
324
+ * this.left = (left===undefined ? null : left)
325
+ * this.right = (right===undefined ? null : right)
326
+ * }
327
+ */
328
+ /**
329
+ * @param {TreeNode} root
330
+ * @return {number}
331
+ */
332
+ var countNodes = function (root ) {
333
+ const depth = root => {
334
+ let d = 0 ;
335
+ for (; root; root = root .left ) {
336
+ ++ d;
337
+ }
338
+ return d;
226
339
};
340
+ if (! root) {
341
+ return 0 ;
342
+ }
227
343
const left = depth (root .left );
228
344
const right = depth (root .right );
229
345
if (left == right) {
@@ -251,23 +367,47 @@ var countNodes = function (root) {
251
367
*/
252
368
public class Solution {
253
369
public int CountNodes (TreeNode root ) {
254
- if (root == null )
255
- {
370
+ if (root == null ) {
371
+ return 0 ;
372
+ }
373
+ return 1 + CountNodes (root .left ) + CountNodes (root .right );
374
+ }
375
+ }
376
+ ```
377
+
378
+ ``` cs
379
+ /**
380
+ * Definition for a binary tree node.
381
+ * public class TreeNode {
382
+ * public int val;
383
+ * public TreeNode left;
384
+ * public TreeNode right;
385
+ * public TreeNode(int val=0, TreeNode left=null, TreeNode right=null) {
386
+ * this.val = val;
387
+ * this.left = left;
388
+ * this.right = right;
389
+ * }
390
+ * }
391
+ */
392
+ public class Solution {
393
+ public int CountNodes (TreeNode root ) {
394
+ if (root == null ) {
256
395
return 0 ;
257
396
}
258
397
int left = depth (root .left );
259
398
int right = depth (root .right );
260
- if (left == right )
261
- {
399
+ if (left == right ) {
262
400
return (1 << left ) + CountNodes (root .right );
263
401
}
264
402
return (1 << right ) + CountNodes (root .left );
265
403
}
266
404
267
405
private int depth (TreeNode root ) {
268
- int res = 0 ;
269
- for (; root != null ; ++ res , root = root .left );
270
- return res ;
406
+ int d = 0 ;
407
+ for (; root != null ; root = root .left ) {
408
+ ++ d ;
409
+ }
410
+ return d ;
271
411
}
272
412
}
273
413
```
0 commit comments