Skip to content

Commit 46fb51f

Browse files
committed
binary_tree done
1 parent a97e380 commit 46fb51f

File tree

2 files changed

+22
-52
lines changed

2 files changed

+22
-52
lines changed

advanced_algorithm/recursion.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
将大问题转化为小问题,通过递归依次解决各个小问题
66

7+
模板:先终止条件,再分类讨论、递归调用、合并结果。
8+
79
## 示例
810

911
### [reverse-string](https://leetcode-cn.com/problems/reverse-string/)

data_structure/binary_tree.md

Lines changed: 20 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ class Solution:
235235
# 可以递归内部函数,也可以递归自己
236236
```
237237

238-
或者反过来计算深度:
238+
或者反过来计算深度:(但是,在下一道判断平衡二叉树时,还是叶子节点从0起返回更好)
239239
```python
240240
class Solution:
241241
def maxDepth(self, root: TreeNode) -> int:
@@ -246,7 +246,7 @@ class Solution:
246246
return depth(root, 0)
247247
```
248248

249-
- 思路 2:层序遍历
249+
- 思路 2:层序遍历(略过了)
250250

251251
```Python
252252
class Solution:
@@ -340,14 +340,14 @@ class Solution:
340340

341341
def largest_path_ends_at(node):
342342
if node is None:
343-
return float('-inf')
343+
return float('-inf') # 记住这里返回-inf而非0!例如输入[-3],左右向答案的贡献变成了0
344344

345345
e_l = largest_path_ends_at(node.left)
346346
e_r = largest_path_ends_at(node.right)
347347

348348
self.maxPath = max(self.maxPath, node.val + max(0, e_l) + max(0, e_r), e_l, e_r)
349349

350-
return node.val + max(e_l, e_r, 0)
350+
return node.val + max(e_l, e_r, 0) # 这里有个0,处理叶子节点返回值
351351

352352
largest_path_ends_at(root)
353353
return self.maxPath
@@ -400,7 +400,7 @@ class Solution:
400400
level = collections.deque([])
401401
append_this = level.append
402402

403-
while len(bfs) > 0:
403+
while bfs:
404404
level_size = len(bfs)
405405
for _ in range(level_size):
406406
node = bfs.popleft()
@@ -445,61 +445,29 @@ class Solution:
445445

446446
- 利用性质:BST中序遍历应得到升序序列。递归中序遍历仍不能提前输出,故用非递归遍历的模板。
447447

448-
TODO:
449-
450-
451-
- 思路 2:分治法,一个二叉树为合法的二叉搜索树当且仅当左右子树为合法二叉搜索树且根结点值大于右子树最小值小于左子树最大值。缺点是若不用迭代形式实现则无法提前返回,而迭代实现右比较复杂。
452-
453-
```Python
448+
```python
454449
class Solution:
455450
def isValidBST(self, root: TreeNode) -> bool:
456-
457-
if root is None: return True
458-
459-
def valid_min_max(node):
460-
461-
isValid = True
462-
if node.left is not None:
463-
l_isValid, l_min, l_max = valid_min_max(node.left)
464-
isValid = isValid and node.val > l_max
465-
else:
466-
l_isValid, l_min = True, node.val
451+
pre_val = float('-inf') # result
452+
WHITE, GRAY = 0, 1
453+
s = [(WHITE, root)]
467454

468-
if node.right is not None:
469-
r_isValid, r_min, r_max = valid_min_max(node.right)
470-
isValid = isValid and node.val < r_min
455+
while s:
456+
color, node = s.pop()
457+
if node is None: continue
458+
if color == WHITE:
459+
s.append((WHITE, node.right))
460+
s.append((GRAY, node))
461+
s.append((WHITE, node.left))
471462
else:
472-
r_isValid, r_max = True, node.val
473-
474-
475-
return l_isValid and r_isValid and isValid, l_min, r_max
476-
477-
return valid_min_max(root)[0]
478-
```
479-
480-
- 思路 3:利用二叉搜索树的性质,根结点为左子树的右边界,右子树的左边界,使用先序遍历自顶向下更新左右子树的边界并检查是否合法,迭代版本实现简单且可以提前返回结果。
481-
482-
```Python
483-
class Solution:
484-
def isValidBST(self, root: TreeNode) -> bool:
485-
486-
if root is None:
487-
return True
488-
489-
s = [(root, float('-inf'), float('inf'))]
490-
while len(s) > 0:
491-
node, low, up = s.pop()
492-
if node.left is not None:
493-
if node.left.val <= low or node.left.val >= node.val:
463+
if node.val <= pre_val:
494464
return False
495-
s.append((node.left, low, node.val))
496-
if node.right is not None:
497-
if node.right.val <= node.val or node.right.val >= up:
498-
return False
499-
s.append((node.right, node.val, up))
465+
pre_val = node.val # result
466+
500467
return True
501468
```
502469

470+
503471
#### [insert-into-a-binary-search-tree](https://leetcode-cn.com/problems/insert-into-a-binary-search-tree/)
504472

505473
> 给定二叉搜索树(BST)的根节点和要插入树中的值,将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。

0 commit comments

Comments
 (0)