@@ -203,6 +203,27 @@ class Solution:
203
203
return levels
204
204
```
205
205
206
+ 关键点:想办法只遍历当前层。上面的方法是在遍历前,计算当前层的节点数。下面的方法是在遍历时,将新产生的节点加入一个临时数组,结束后再合并。双端队列并非关键。
207
+
208
+ ``` python
209
+ class Solution :
210
+ def levelOrder (self , root : Optional[TreeNode]) -> List[List[int ]]:
211
+ outs = []
212
+ nodes = [root]
213
+ while nodes:
214
+ nodes_t = []
215
+ values = []
216
+ for node in nodes:
217
+ if node is None :
218
+ continue
219
+ nodes_t.extend([node.left, node.right])
220
+ values.append(node.val)
221
+ if values:
222
+ outs.append(values)
223
+ nodes = nodes_t
224
+ return outs
225
+ ```
226
+
206
227
### 分治法应用
207
228
208
229
先分别处理局部,再合并结果
@@ -225,7 +246,7 @@ class Solution:
225
246
226
247
> 给定一个二叉树,找出其最大深度。
227
248
228
- - 思路 1:分治法
249
+ - 思路 1:分治法(递归)
229
250
230
251
``` Python
231
252
class Solution :
@@ -270,55 +291,53 @@ class Solution:
270
291
271
292
``` Python
272
293
class Solution :
273
- def isBalanced (self , root : TreeNode) -> bool :
274
-
275
- def depth (root ):
276
-
277
- if root is None :
278
- return 0 , True
279
-
280
- dl, bl = depth(root.left)
281
- dr, br = depth(root.right)
282
-
283
- return max (dl, dr) + 1 , bl and br and abs (dl - dr) < 2
284
-
285
- _, out = depth(root)
286
-
287
- return out
294
+ def isBalanced (self , root : Optional[TreeNode]) -> bool :
295
+ balanced = True
296
+
297
+ def isBalancedS (root ):
298
+ nonlocal balanced
299
+ if not root: return
300
+ stack = [(root, 1 )] # node, isTree
301
+ heights = {}
302
+ while balanced and stack:
303
+ node, isTree = stack.pop()
304
+ if isTree:
305
+ stack.append((node, 0 ))
306
+ if n:= node.right:
307
+ stack.append((n, 1 ))
308
+ if n:= node.left:
309
+ stack.append((n, 1 ))
310
+ else :
311
+ left_height = heights.get(node.left, 0 ) if node.left else 0
312
+ right_height = heights.get(node.right, 0 ) if node.right else 0
313
+ if abs (left_height - right_height) > 1 :
314
+ balanced = False
315
+ return
316
+ heights[node] = 1 + max (left_height, right_height)
317
+
318
+ def isBalancedC (node ):
319
+ nonlocal balanced
320
+ if (not balanced) or (node is None ) :
321
+ return 0
322
+
323
+ l_d = isBalancedC(node.left)
324
+ r_d = isBalancedC(node.right)
325
+
326
+ if abs (l_d - r_d) > 1 :
327
+ balanced = False
328
+ return 0
329
+
330
+ return 1 + max (l_d, r_d)
331
+
332
+ isBalancedS(root)
333
+ return balanced
288
334
```
289
335
290
336
- 思路 2:使用后序遍历实现分治法的迭代版本
337
+ - 为什么要后序遍历呢?观察上面的分治法(递归法),自然而然的就是后序遍历递归的变体。
338
+ - 非递归法的难点:存储高度信息。解法:引入额外字典结构,以节点为键存储高度信息。
291
339
292
- ``` Python
293
- class Solution :
294
- def isBalanced (self , root : TreeNode) -> bool :
295
-
296
- s = [[TreeNode(), - 1 , - 1 ]]
297
- node, last = root, None
298
- while len (s) > 1 or node is not None :
299
- if node is not None :
300
- s.append([node, - 1 , - 1 ])
301
- node = node.left
302
- if node is None :
303
- s[- 1 ][1 ] = 0
304
- else :
305
- peek = s[- 1 ][0 ]
306
- if peek.right is not None and last != peek.right:
307
- node = peek.right
308
- else :
309
- if peek.right is None :
310
- s[- 1 ][2 ] = 0
311
- last, dl, dr = s.pop()
312
- if abs (dl - dr) > 1 :
313
- return False
314
- d = max (dl, dr) + 1
315
- if s[- 1 ][1 ] == - 1 :
316
- s[- 1 ][1 ] = d
317
- else :
318
- s[- 1 ][2 ] = d
319
-
320
- return True
321
- ```
340
+ TODO: 似乎还可以使用中序遍历的非递归方法来写:[ https://leetcode.cn/problems/balanced-binary-tree/solutions/2099334/tu-jie-leetcode-ping-heng-er-cha-shu-di-gogyi ]
322
341
323
342
### [ binary-tree-maximum-path-sum] ( https://leetcode-cn.com/problems/binary-tree-maximum-path-sum/ )
324
343
0 commit comments