Skip to content

Commit 5c7811f

Browse files
二叉树
1 parent ff8072f commit 5c7811f

File tree

1 file changed

+65
-46
lines changed

1 file changed

+65
-46
lines changed

2.data_structure/1. binary_tree.md renamed to 2.data_structure/1.binary_tree.md

Lines changed: 65 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,27 @@ class Solution:
203203
return levels
204204
```
205205

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+
206227
### 分治法应用
207228

208229
先分别处理局部,再合并结果
@@ -225,7 +246,7 @@ class Solution:
225246

226247
> 给定一个二叉树,找出其最大深度。
227248
228-
- 思路 1:分治法
249+
- 思路 1:分治法(递归)
229250

230251
```Python
231252
class Solution:
@@ -270,55 +291,53 @@ class Solution:
270291

271292
```Python
272293
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
288334
```
289335

290336
- 思路 2:使用后序遍历实现分治法的迭代版本
337+
- 为什么要后序遍历呢?观察上面的分治法(递归法),自然而然的就是后序遍历递归的变体。
338+
- 非递归法的难点:存储高度信息。解法:引入额外字典结构,以节点为键存储高度信息。
291339

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]
322341

323342
### [binary-tree-maximum-path-sum](https://leetcode-cn.com/problems/binary-tree-maximum-path-sum/)
324343

0 commit comments

Comments
 (0)