Merge pull request #2083 from jianghongcheng/master

Update 0106.从中序与后序遍历序列构造二叉树.md
This commit is contained in:
程序员Carl
2023-05-23 20:42:12 +08:00
committed by GitHub
8 changed files with 267 additions and 162 deletions

View File

@ -400,8 +400,6 @@ public:
}; };
``` ```
## Python
# 105.从前序与中序遍历序列构造二叉树 # 105.从前序与中序遍历序列构造二叉树
@ -692,38 +690,6 @@ class Solution {
## Python ## Python
```python
class Solution:
def buildTree(self, inorder: List[int], postorder: List[int]) -> Optional[TreeNode]:
# 第一步: 特殊情况讨论: 树为空. 或者说是递归终止条件
if not postorder:
return
# 第二步: 后序遍历的最后一个就是当前的中间节点
root_val = postorder[-1]
root = TreeNode(root_val)
# 第三步: 找切割点.
root_index = inorder.index(root_val)
# 第四步: 切割inorder数组. 得到inorder数组的左,右半边.
left_inorder = inorder[:root_index]
right_inorder = inorder[root_index + 1:]
# 第五步: 切割postorder数组. 得到postorder数组的左,右半边.
# ⭐️ 重点1: 中序数组大小一定跟后序数组大小是相同的.
left_postorder = postorder[:len(left_inorder)]
right_postorder = postorder[len(left_inorder): len(postorder) - 1]
# 第六步: 递归
root.left = self.buildTree(left_inorder, left_postorder)
root.right = self.buildTree(right_inorder, right_postorder)
# 第七步: 返回答案
return root
```
105.从前序与中序遍历序列构造二叉树 105.从前序与中序遍历序列构造二叉树
```python ```python
@ -752,7 +718,7 @@ class Solution:
# 第六步: 递归 # 第六步: 递归
root.left = self.buildTree(preorder_left, inorder_left) root.left = self.buildTree(preorder_left, inorder_left)
root.right = self.buildTree(preorder_right, inorder_right) root.right = self.buildTree(preorder_right, inorder_right)
# 第七步: 返回答案
return root return root
``` ```
@ -784,7 +750,7 @@ class Solution:
# 第六步: 递归 # 第六步: 递归
root.left = self.buildTree(inorder_left, postorder_left) root.left = self.buildTree(inorder_left, postorder_left)
root.right = self.buildTree(inorder_right, postorder_right) root.right = self.buildTree(inorder_right, postorder_right)
# 第七步: 返回答案
return root return root
``` ```

View File

@ -553,6 +553,52 @@ class Solution:
迭代法: 迭代法:
```python
class Solution:
def getDepth(self, cur):
st = []
if cur is not None:
st.append(cur)
depth = 0
result = 0
while st:
node = st[-1]
if node is not None:
st.pop()
st.append(node) # 中
st.append(None)
depth += 1
if node.right:
st.append(node.right) # 右
if node.left:
st.append(node.left) # 左
else:
node = st.pop()
st.pop()
depth -= 1
result = max(result, depth)
return result
def isBalanced(self, root):
st = []
if root is None:
return True
st.append(root)
while st:
node = st.pop() # 中
if abs(self.getDepth(node.left) - self.getDepth(node.right)) > 1:
return False
if node.right:
st.append(node.right) # 右(空节点不入栈)
if node.left:
st.append(node.left) # 左(空节点不入栈)
return True
```
迭代法精简版:
```python ```python
class Solution: class Solution:
def isBalanced(self, root: Optional[TreeNode]) -> bool: def isBalanced(self, root: Optional[TreeNode]) -> bool:
@ -576,8 +622,6 @@ class Solution:
height_map[real_node] = 1 + max(left, right) height_map[real_node] = 1 + max(left, right)
return True return True
``` ```
### Go ### Go
```Go ```Go

View File

@ -470,38 +470,34 @@ class Solution {
## Python: ## Python:
递归法+回溯(版本一) 递归法+回溯
```Python ```Python
# Definition for a binary tree node. # Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
import copy
from typing import List, Optional
class Solution: class Solution:
def binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]: def traversal(self, cur, path, result):
if not root: path.append(cur.val) # 中
return [] if not cur.left and not cur.right: # 到达叶子节点
sPath = '->'.join(map(str, path))
result.append(sPath)
return
if cur.left: # 左
self.traversal(cur.left, path, result)
path.pop() # 回溯
if cur.right: # 右
self.traversal(cur.right, path, result)
path.pop() # 回溯
def binaryTreePaths(self, root):
result = [] result = []
self.generate_paths(root, [], result) path = []
if not root:
return result
self.traversal(root, path, result)
return result return result
def generate_paths(self, node: TreeNode, path: List[int], result: List[str]) -> None:
path.append(node.val)
if not node.left and not node.right:
result.append('->'.join(map(str, path)))
if node.left:
self.generate_paths(node.left, copy.copy(path), result)
if node.right:
self.generate_paths(node.right, copy.copy(path), result)
path.pop()
``` ```
递归法+回溯(版本 递归法+隐形回溯(版本
```Python ```Python
# Definition for a binary tree node. # Definition for a binary tree node.
# class TreeNode: # class TreeNode:
@ -509,7 +505,6 @@ class Solution:
# self.val = val # self.val = val
# self.left = left # self.left = left
# self.right = right # self.right = right
import copy
from typing import List, Optional from typing import List, Optional
class Solution: class Solution:
@ -517,23 +512,23 @@ class Solution:
if not root: if not root:
return [] return []
result = [] result = []
self.generate_paths(root, [], result) self.traversal(root, [], result)
return result return result
def generate_paths(self, node: TreeNode, path: List[int], result: List[str]) -> None: def traversal(self, cur: TreeNode, path: List[int], result: List[str]) -> None:
if not node: if not cur:
return return
path.append(node.val) path.append(cur.val)
if not node.left and not node.right: if not cur.left and not cur.right:
result.append('->'.join(map(str, path))) result.append('->'.join(map(str, path)))
else: if cur.left:
self.generate_paths(node.left, copy.copy(path), result) self.traversal(cur.left, path[:], result)
self.generate_paths(node.right, copy.copy(path), result) if cur.right:
path.pop() self.traversal(cur.right, path[:], result)
``` ```
递归法+隐形回溯 递归法+隐形回溯(版本二)
```Python ```Python
# Definition for a binary tree node. # Definition for a binary tree node.
# class TreeNode: # class TreeNode:
@ -566,16 +561,11 @@ class Solution:
迭代法: 迭代法:
```Python ```Python
from collections import deque
class Solution: class Solution:
"""二叉树的所有路径 迭代法"""
def binaryTreePaths(self, root: TreeNode) -> List[str]: def binaryTreePaths(self, root: TreeNode) -> List[str]:
# 题目中节点数至少为1 # 题目中节点数至少为1
stack, path_st, result = deque([root]), deque(), [] stack, path_st, result = [root], [str(root.val)], []
path_st.append(str(root.val))
while stack: while stack:
cur = stack.pop() cur = stack.pop()

View File

@ -247,8 +247,7 @@ class Solution {
### Python ### Python
递归
**递归后序遍历**
```python ```python
# Definition for a binary tree node. # Definition for a binary tree node.
# class TreeNode: # class TreeNode:
@ -257,47 +256,64 @@ class Solution {
# self.left = left # self.left = left
# self.right = right # self.right = right
class Solution: class Solution:
def sumOfLeftLeaves(self, root: Optional[TreeNode]) -> int: def sumOfLeftLeaves(self, root):
if not root: if root is None:
return 0
if root.left is None and root.right is None:
return 0 return 0
# 检查根节点的左子节点是否为叶节点 leftValue = self.sumOfLeftLeaves(root.left) # 左
if root.left and not root.left.left and not root.left.right: if root.left and not root.left.left and not root.left.right: # 左子树是左叶子的情况
left_val = root.left.val leftValue = root.left.val
else:
left_val = self.sumOfLeftLeaves(root.left)
# 递归地计算右子树左叶节点的和 rightValue = self.sumOfLeftLeaves(root.right) # 右
right_val = self.sumOfLeftLeaves(root.right)
sum_val = leftValue + rightValue # 中
return left_val + right_val return sum_val
```
递归精简版
```python
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def sumOfLeftLeaves(self, root):
if root is None:
return 0
leftValue = 0
if root.left is not None and root.left.left is None and root.left.right is None:
leftValue = root.left.val
return leftValue + self.sumOfLeftLeaves(root.left) + self.sumOfLeftLeaves(root.right)
``` ```
**迭代** 迭代法
```python ```python
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution: class Solution:
def sumOfLeftLeaves(self, root: TreeNode) -> int: def sumOfLeftLeaves(self, root):
""" if root is None:
Idea: Each time check current node's left node. return 0
If current node don't have one, skip it. st = [root]
""" result = 0
stack = [] while st:
if root: node = st.pop()
stack.append(root) if node.left and node.left.left is None and node.left.right is None:
res = 0 result += node.left.val
if node.right:
while stack: st.append(node.right)
# 每次都把当前节点的左节点加进去. if node.left:
cur_node = stack.pop() st.append(node.left)
if cur_node.left and not cur_node.left.left and not cur_node.left.right: return result
res += cur_node.left.val
if cur_node.left:
stack.append(cur_node.left)
if cur_node.right:
stack.append(cur_node.right)
return res
``` ```
### Go ### Go

View File

@ -330,19 +330,24 @@ class Solution:
# self.right = right # self.right = right
from collections import deque from collections import deque
class Solution: class Solution:
def findBottomLeftValue(self, root: Optional[TreeNode]) -> int: def findBottomLeftValue(self, root):
queue = deque([root]) if root is None:
return 0
queue = deque()
queue.append(root)
result = 0
while queue: while queue:
size = len(queue) size = len(queue)
leftmost = queue[0].val
for i in range(size): for i in range(size):
node = queue.popleft() node = queue.popleft()
if i == 0:
result = node.val
if node.left: if node.left:
queue.append(node.left) queue.append(node.left)
if node.right: if node.right:
queue.append(node.right) queue.append(node.right)
if not queue: return result
return leftmost
``` ```

View File

@ -352,8 +352,7 @@ class Solution {
``` ```
### Python ### Python
(版本一) 递归 - 前序 - 修改root1
**递归法 - 前序遍历**
```python ```python
# Definition for a binary tree node. # Definition for a binary tree node.
# class TreeNode: # class TreeNode:
@ -377,8 +376,33 @@ class Solution:
return root1 # ⚠️ 注意: 本题我们重复使用了题目给出的节点而不是创建新节点. 节省时间, 空间. return root1 # ⚠️ 注意: 本题我们重复使用了题目给出的节点而不是创建新节点. 节省时间, 空间.
``` ```
(版本二) 递归 - 前序 - 新建root
```python
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def mergeTrees(self, root1: TreeNode, root2: TreeNode) -> TreeNode:
# 递归终止条件:
# 但凡有一个节点为空, 就立刻返回另外一个. 如果另外一个也为None就直接返回None.
if not root1:
return root2
if not root2:
return root1
# 上面的递归终止条件保证了代码执行到这里root1, root2都非空.
root = TreeNode() # 创建新节点
root.val += root1.val + root2.val# 中
root.left = self.mergeTrees(root1.left, root2.left) #左
root.right = self.mergeTrees(root1.right, root2.right) # 右
return root # ⚠️ 注意: 本题我们创建了新节点.
**迭代法** ```
(版本三) 迭代
```python ```python
class Solution: class Solution:
def mergeTrees(self, root1: TreeNode, root2: TreeNode) -> TreeNode: def mergeTrees(self, root1: TreeNode, root2: TreeNode) -> TreeNode:
@ -413,7 +437,44 @@ class Solution:
return root1 return root1
``` ```
(版本四) 迭代 + 代码优化
```python
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
from collections import deque
class Solution:
def mergeTrees(self, root1: TreeNode, root2: TreeNode) -> TreeNode:
if not root1:
return root2
if not root2:
return root1
queue = deque()
queue.append((root1, root2))
while queue:
node1, node2 = queue.popleft()
node1.val += node2.val
if node1.left and node2.left:
queue.append((node1.left, node2.left))
elif not node1.left:
node1.left = node2.left
if node1.right and node2.right:
queue.append((node1.right, node2.right))
elif not node1.right:
node1.right = node2.right
return root1
```
### Go ### Go
```go ```go

View File

@ -259,52 +259,75 @@ class Solution {
``` ```
### Python ### Python
(版本一) 基础版
```python ```python
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution: class Solution:
"""递归法 更快"""
def constructMaximumBinaryTree(self, nums: List[int]) -> TreeNode: def constructMaximumBinaryTree(self, nums: List[int]) -> TreeNode:
if not nums: if len(nums) == 1:
return None return TreeNode(nums[0])
maxvalue = max(nums) node = TreeNode(0)
index = nums.index(maxvalue) # 找到数组中最大的值和对应的下标
maxValue = 0
maxValueIndex = 0
for i in range(len(nums)):
if nums[i] > maxValue:
maxValue = nums[i]
maxValueIndex = i
node.val = maxValue
# 最大值所在的下标左区间 构造左子树
if maxValueIndex > 0:
new_list = nums[:maxValueIndex]
node.left = self.constructMaximumBinaryTree(new_list)
# 最大值所在的下标右区间 构造右子树
if maxValueIndex < len(nums) - 1:
new_list = nums[maxValueIndex+1:]
node.right = self.constructMaximumBinaryTree(new_list)
return node
root = TreeNode(maxvalue) ```
(版本二) 使用下标
```python
left = nums[:index]
right = nums[index + 1:]
root.left = self.constructMaximumBinaryTree(left)
root.right = self.constructMaximumBinaryTree(right)
return root
class Solution: class Solution:
"""最大二叉树 递归法""" def traversal(self, nums: List[int], left: int, right: int) -> TreeNode:
if left >= right:
return None
maxValueIndex = left
for i in range(left + 1, right):
if nums[i] > nums[maxValueIndex]:
maxValueIndex = i
root = TreeNode(nums[maxValueIndex])
root.left = self.traversal(nums, left, maxValueIndex)
root.right = self.traversal(nums, maxValueIndex + 1, right)
return root
def constructMaximumBinaryTree(self, nums: List[int]) -> TreeNode: def constructMaximumBinaryTree(self, nums: List[int]) -> TreeNode:
return self.traversal(nums, 0, len(nums)) return self.traversal(nums, 0, len(nums))
def traversal(self, nums: List[int], begin: int, end: int) -> TreeNode:
# 列表长度为0时返回空节点
if begin == end:
return None
# 找到最大的值和其对应的下标
max_index = begin
for i in range(begin, end):
if nums[i] > nums[max_index]:
max_index = i
# 构建当前节点
root = TreeNode(nums[max_index])
# 递归构建左右子树
root.left = self.traversal(nums, begin, max_index)
root.right = self.traversal(nums, max_index + 1, end)
return root
```
```
(版本三) 使用切片
```python
class Solution:
def constructMaximumBinaryTree(self, nums: List[int]) -> TreeNode:
if not nums:
return None
max_val = max(nums)
max_index = nums.index(max_val)
node = TreeNode(max_val)
node.left = self.constructMaximumBinaryTree(nums[:max_index])
node.right = self.constructMaximumBinaryTree(nums[max_index+1:])
return node
```
### Go ### Go

View File

@ -230,7 +230,7 @@ class Solution {
### Python ### Python
递归法: (方法一) 递归
```python ```python
class Solution: class Solution:
@ -250,12 +250,12 @@ class Solution:
``` ```
迭代法: (方法二)迭代
```python ```python
class Solution: class Solution:
def searchBST(self, root: TreeNode, val: int) -> TreeNode: def searchBST(self, root: TreeNode, val: int) -> TreeNode:
while root is not None: while root:
if val < root.val: root = root.left if val < root.val: root = root.left
elif val > root.val: root = root.right elif val > root.val: root = root.right
else: return root else: return root