mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-12 05:20:59 +08:00
Merge pull request #2083 from jianghongcheng/master
Update 0106.从中序与后序遍历序列构造二叉树.md
This commit is contained in:
@ -400,8 +400,6 @@ public:
|
||||
};
|
||||
```
|
||||
|
||||
## Python
|
||||
|
||||
|
||||
# 105.从前序与中序遍历序列构造二叉树
|
||||
|
||||
@ -692,38 +690,6 @@ class Solution {
|
||||
|
||||
## 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.从前序与中序遍历序列构造二叉树
|
||||
|
||||
```python
|
||||
@ -752,7 +718,7 @@ class Solution:
|
||||
# 第六步: 递归
|
||||
root.left = self.buildTree(preorder_left, inorder_left)
|
||||
root.right = self.buildTree(preorder_right, inorder_right)
|
||||
|
||||
# 第七步: 返回答案
|
||||
return root
|
||||
```
|
||||
|
||||
@ -784,7 +750,7 @@ class Solution:
|
||||
# 第六步: 递归
|
||||
root.left = self.buildTree(inorder_left, postorder_left)
|
||||
root.right = self.buildTree(inorder_right, postorder_right)
|
||||
|
||||
# 第七步: 返回答案
|
||||
return root
|
||||
```
|
||||
|
||||
|
@ -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
|
||||
class Solution:
|
||||
def isBalanced(self, root: Optional[TreeNode]) -> bool:
|
||||
@ -576,8 +622,6 @@ class Solution:
|
||||
height_map[real_node] = 1 + max(left, right)
|
||||
return True
|
||||
```
|
||||
|
||||
|
||||
### Go
|
||||
|
||||
```Go
|
||||
|
@ -470,70 +470,65 @@ class Solution {
|
||||
## 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
|
||||
import copy
|
||||
from typing import List, Optional
|
||||
|
||||
class Solution:
|
||||
def binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]:
|
||||
if not root:
|
||||
return []
|
||||
result = []
|
||||
self.generate_paths(root, [], 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
|
||||
# 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:
|
||||
def binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]:
|
||||
if not root:
|
||||
return []
|
||||
result = []
|
||||
self.generate_paths(root, [], result)
|
||||
return result
|
||||
|
||||
def generate_paths(self, node: TreeNode, path: List[int], result: List[str]) -> None:
|
||||
if not node:
|
||||
def traversal(self, cur, path, result):
|
||||
path.append(cur.val) # 中
|
||||
if not cur.left and not cur.right: # 到达叶子节点
|
||||
sPath = '->'.join(map(str, path))
|
||||
result.append(sPath)
|
||||
return
|
||||
path.append(node.val)
|
||||
if not node.left and not node.right:
|
||||
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 = []
|
||||
path = []
|
||||
if not root:
|
||||
return result
|
||||
self.traversal(root, path, result)
|
||||
return result
|
||||
|
||||
|
||||
```
|
||||
递归法+隐形回溯(版本一)
|
||||
```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 typing import List, Optional
|
||||
|
||||
class Solution:
|
||||
def binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]:
|
||||
if not root:
|
||||
return []
|
||||
result = []
|
||||
self.traversal(root, [], result)
|
||||
return result
|
||||
|
||||
def traversal(self, cur: TreeNode, path: List[int], result: List[str]) -> None:
|
||||
if not cur:
|
||||
return
|
||||
path.append(cur.val)
|
||||
if not cur.left and not cur.right:
|
||||
result.append('->'.join(map(str, path)))
|
||||
else:
|
||||
self.generate_paths(node.left, copy.copy(path), result)
|
||||
self.generate_paths(node.right, copy.copy(path), result)
|
||||
path.pop()
|
||||
if cur.left:
|
||||
self.traversal(cur.left, path[:], result)
|
||||
if cur.right:
|
||||
self.traversal(cur.right, path[:], result)
|
||||
|
||||
```
|
||||
|
||||
递归法+隐形回溯
|
||||
递归法+隐形回溯(版本二)
|
||||
```Python
|
||||
# Definition for a binary tree node.
|
||||
# class TreeNode:
|
||||
@ -566,16 +561,11 @@ class Solution:
|
||||
迭代法:
|
||||
|
||||
```Python
|
||||
from collections import deque
|
||||
|
||||
|
||||
class Solution:
|
||||
"""二叉树的所有路径 迭代法"""
|
||||
|
||||
def binaryTreePaths(self, root: TreeNode) -> List[str]:
|
||||
# 题目中节点数至少为1
|
||||
stack, path_st, result = deque([root]), deque(), []
|
||||
path_st.append(str(root.val))
|
||||
stack, path_st, result = [root], [str(root.val)], []
|
||||
|
||||
while stack:
|
||||
cur = stack.pop()
|
||||
|
@ -247,8 +247,7 @@ class Solution {
|
||||
|
||||
|
||||
### Python
|
||||
|
||||
**递归后序遍历**
|
||||
递归
|
||||
```python
|
||||
# Definition for a binary tree node.
|
||||
# class TreeNode:
|
||||
@ -257,47 +256,64 @@ class Solution {
|
||||
# self.left = left
|
||||
# self.right = right
|
||||
class Solution:
|
||||
def sumOfLeftLeaves(self, root: Optional[TreeNode]) -> int:
|
||||
if not root:
|
||||
def sumOfLeftLeaves(self, root):
|
||||
if root is None:
|
||||
return 0
|
||||
if root.left is None and root.right is None:
|
||||
return 0
|
||||
|
||||
# 检查根节点的左子节点是否为叶节点
|
||||
if root.left and not root.left.left and not root.left.right:
|
||||
left_val = root.left.val
|
||||
else:
|
||||
left_val = self.sumOfLeftLeaves(root.left)
|
||||
leftValue = self.sumOfLeftLeaves(root.left) # 左
|
||||
if root.left and not root.left.left and not root.left.right: # 左子树是左叶子的情况
|
||||
leftValue = root.left.val
|
||||
|
||||
# 递归地计算右子树左叶节点的和
|
||||
right_val = self.sumOfLeftLeaves(root.right)
|
||||
rightValue = self.sumOfLeftLeaves(root.right) # 右
|
||||
|
||||
return left_val + right_val
|
||||
sum_val = leftValue + rightValue # 中
|
||||
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
|
||||
# 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: TreeNode) -> int:
|
||||
"""
|
||||
Idea: Each time check current node's left node.
|
||||
If current node don't have one, skip it.
|
||||
"""
|
||||
stack = []
|
||||
if root:
|
||||
stack.append(root)
|
||||
res = 0
|
||||
def sumOfLeftLeaves(self, root):
|
||||
if root is None:
|
||||
return 0
|
||||
st = [root]
|
||||
result = 0
|
||||
while st:
|
||||
node = st.pop()
|
||||
if node.left and node.left.left is None and node.left.right is None:
|
||||
result += node.left.val
|
||||
if node.right:
|
||||
st.append(node.right)
|
||||
if node.left:
|
||||
st.append(node.left)
|
||||
return result
|
||||
|
||||
while stack:
|
||||
# 每次都把当前节点的左节点加进去.
|
||||
cur_node = stack.pop()
|
||||
if cur_node.left and not cur_node.left.left and not cur_node.left.right:
|
||||
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
|
||||
|
@ -330,19 +330,24 @@ class Solution:
|
||||
# self.right = right
|
||||
from collections import deque
|
||||
class Solution:
|
||||
def findBottomLeftValue(self, root: Optional[TreeNode]) -> int:
|
||||
queue = deque([root])
|
||||
def findBottomLeftValue(self, root):
|
||||
if root is None:
|
||||
return 0
|
||||
queue = deque()
|
||||
queue.append(root)
|
||||
result = 0
|
||||
while queue:
|
||||
size = len(queue)
|
||||
leftmost = queue[0].val
|
||||
for i in range(size):
|
||||
node = queue.popleft()
|
||||
if i == 0:
|
||||
result = node.val
|
||||
if node.left:
|
||||
queue.append(node.left)
|
||||
if node.right:
|
||||
queue.append(node.right)
|
||||
if not queue:
|
||||
return leftmost
|
||||
return result
|
||||
|
||||
|
||||
|
||||
```
|
||||
|
@ -352,8 +352,7 @@ class Solution {
|
||||
```
|
||||
|
||||
### Python
|
||||
|
||||
**递归法 - 前序遍历**
|
||||
(版本一) 递归 - 前序 - 修改root1
|
||||
```python
|
||||
# Definition for a binary tree node.
|
||||
# class TreeNode:
|
||||
@ -377,8 +376,33 @@ class Solution:
|
||||
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
|
||||
class Solution:
|
||||
def mergeTrees(self, root1: TreeNode, root2: TreeNode) -> TreeNode:
|
||||
@ -413,7 +437,44 @@ class Solution:
|
||||
|
||||
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
|
||||
|
@ -259,52 +259,75 @@ class Solution {
|
||||
```
|
||||
|
||||
### 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:
|
||||
"""递归法 更快"""
|
||||
def constructMaximumBinaryTree(self, nums: List[int]) -> TreeNode:
|
||||
if not nums:
|
||||
return None
|
||||
maxvalue = max(nums)
|
||||
index = nums.index(maxvalue)
|
||||
if len(nums) == 1:
|
||||
return TreeNode(nums[0])
|
||||
node = TreeNode(0)
|
||||
# 找到数组中最大的值和对应的下标
|
||||
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)
|
||||
|
||||
left = nums[:index]
|
||||
right = nums[index + 1:]
|
||||
|
||||
root.left = self.constructMaximumBinaryTree(left)
|
||||
root.right = self.constructMaximumBinaryTree(right)
|
||||
return root
|
||||
```
|
||||
(版本二) 使用下标
|
||||
```python
|
||||
|
||||
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:
|
||||
return self.traversal(nums, 0, len(nums))
|
||||
|
||||
def traversal(self, nums: List[int], begin: int, end: int) -> TreeNode:
|
||||
# 列表长度为0时返回空节点
|
||||
if begin == end:
|
||||
```
|
||||
|
||||
(版本三) 使用切片
|
||||
|
||||
```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
|
||||
|
||||
# 找到最大的值和其对应的下标
|
||||
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
|
||||
```
|
||||
|
||||
### Go
|
||||
|
||||
|
||||
|
@ -230,7 +230,7 @@ class Solution {
|
||||
|
||||
### Python
|
||||
|
||||
递归法:
|
||||
(方法一) 递归
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
@ -250,12 +250,12 @@ class Solution:
|
||||
|
||||
```
|
||||
|
||||
迭代法:
|
||||
(方法二)迭代
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def searchBST(self, root: TreeNode, val: int) -> TreeNode:
|
||||
while root is not None:
|
||||
while root:
|
||||
if val < root.val: root = root.left
|
||||
elif val > root.val: root = root.right
|
||||
else: return root
|
||||
|
Reference in New Issue
Block a user