Skip to content

Commit 426f76c

Browse files
committed
修正内容错误
1 parent cd21345 commit 426f76c

File tree

1 file changed

+60
-8
lines changed

1 file changed

+60
-8
lines changed

docs/solutions/0100-0199/construct-binary-tree-from-preorder-and-inorder-traversal.md

Lines changed: 60 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@
1818
- $1 \le preorder.length \le 3000$。
1919
- $inorder.length == preorder.length$。
2020
- $-3000 \le preorder[i], inorder[i] \le 3000$。
21-
- `preorder``inorder` 均无重复元素。
22-
- `inorder` 均出现在 `preorder`
23-
- `preorder` 保证为二叉树的前序遍历序列。
24-
- `inorder` 保证为二叉树的中序遍历序列。
21+
- $preorder$$inorder$ 均无重复元素。
22+
- $inorder$ 均出现在 $preorder$
23+
- $preorder$ 保证为二叉树的前序遍历序列。
24+
- $inorder$ 保证为二叉树的中序遍历序列。
2525

2626
**示例**
2727

@@ -47,8 +47,8 @@
4747

4848
前序遍历的顺序是:根 -> 左 -> 右。中序遍历的顺序是:左 -> 根 -> 右。根据前序遍历的顺序,可以找到根节点位置。然后在中序遍历的结果中可以找到对应的根节点位置,就可以从根节点位置将二叉树分割成左子树、右子树。同时能得到左右子树的节点个数。此时构建当前节点,并递归建立左右子树,在左右子树对应位置继续递归遍历进行上述步骤,直到节点为空,具体操作步骤如下:
4949

50-
1. 从前序遍历顺序中当前根节点的位置在 `postorder[0]`
51-
2. 通过在中序遍历中查找上一步根节点对应的位置 `inorder[k]`,从而将二叉树的左右子树分隔开,并得到左右子树节点的个数。
50+
1. 从前序遍历顺序中当前根节点的位置在 $postorder[0]$
51+
2. 通过在中序遍历中查找上一步根节点对应的位置 $inorder[k]$,从而将二叉树的左右子树分隔开,并得到左右子树节点的个数。
5252
3. 从上一步得到的左右子树个数将前序遍历结果中的左右子树分开。
5353
4. 构建当前节点,并递归建立左右子树,在左右子树对应位置继续递归遍历并执行上述三步,直到节点为空。
5454

@@ -72,5 +72,57 @@ class Solution:
7272

7373
### 思路 1:复杂度分析
7474

75-
- **时间复杂度**:$O(n)$,其中 $n$ 是二叉树的节点数目。
76-
- **空间复杂度**:$O(n)$。递归函数需要用到栈空间,栈空间取决于递归深度,最坏情况下递归深度为 $n$,所以空间复杂度为 $O(n)$。
75+
- **时间复杂度**:$O(n^2)$,其中 $n$ 是二叉树的节点数目。每次递归都需要在中序遍历数组 `inorder` 中查找根节点的位置,最坏情况下需要遍历整个数组,因此每一层递归的查找操作为 $O(n)$,而递归总共 $n$ 层,所以总时间复杂度为 $O(n^2)$。
76+
- **空间复杂度**:$O(n^2)$。递归过程中每次切片会新建子数组,最坏情况下每层递归都要复制 $O(n)$ 大小的数组,共 $O(n)$ 层,因此总空间复杂度为 $O(n^2)$。如果不考虑切片额外空间,仅考虑递归栈,则为 $O(n)$。
77+
78+
### 思路 2:递归遍历 + 哈希表
79+
80+
在思路 1 中,每次递归都需要在中序遍历数组 $inorder$ 中查找根节点的位置,这导致了 $O(n)$ 的查找时间。我们可以使用哈希表来优化这个过程,将中序遍历数组中每个元素的值与其索引位置建立映射关系,这样查找根节点位置的时间复杂度就可以优化到 $O(1)$。
81+
82+
具体操作步骤如下:
83+
84+
1. 首先遍历中序遍历数组,将每个元素的值与其索引位置建立映射关系,存储在哈希表中。
85+
2. 从前序遍历顺序中当前根节点的位置在 $preorder[0]$。
86+
3. 通过哈希表查找根节点在中序遍历中的位置 $inorder[k]$,从而将二叉树的左右子树分隔开,并得到左右子树节点的个数。
87+
4. 从上一步得到的左右子树个数将前序遍历结果中的左右子树分开。
88+
5. 构建当前节点,并递归建立左右子树,在左右子树对应位置继续递归遍历并执行上述步骤,直到节点为空。
89+
90+
### 思路 2:代码
91+
92+
```python
93+
class Solution:
94+
def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
95+
# 构建中序遍历数组中元素值与索引的映射关系
96+
inorder_map = {val: idx for idx, val in enumerate(inorder)}
97+
98+
def createTree(preorder_left, preorder_right, inorder_left, inorder_right):
99+
if preorder_left > preorder_right:
100+
return None
101+
102+
# 前序遍历的第一个节点就是根节点
103+
root_val = preorder[preorder_left]
104+
root = TreeNode(root_val)
105+
106+
# 在中序遍历中找到根节点的位置
107+
root_index = inorder_map[root_val]
108+
109+
# 计算左子树的节点个数
110+
left_size = root_index - inorder_left
111+
112+
# 递归构建左子树
113+
root.left = createTree(preorder_left + 1, preorder_left + left_size,
114+
inorder_left, root_index - 1)
115+
116+
# 递归构建右子树
117+
root.right = createTree(preorder_left + left_size + 1, preorder_right,
118+
root_index + 1, inorder_right)
119+
120+
return root
121+
122+
return createTree(0, len(preorder) - 1, 0, len(inorder) - 1)
123+
```
124+
125+
### 思路 2:复杂度分析
126+
127+
- **时间复杂度**:$O(n)$,其中 $n$ 是二叉树的节点数目。每个节点都会被访问一次,且通过哈希表查找根节点位置的时间复杂度为 $O(1)$,因此总时间复杂度为 $O(n)$。
128+
- **空间复杂度**:$O(n)$。哈希表需要 $O(n)$ 的空间存储中序遍历数组中元素值与索引的映射关系,递归栈的深度为 $O(h)$,其中 $h$ 是二叉树的高度。在最坏情况下,二叉树退化为链表,此时 $h = n$,所以总空间复杂度为 $O(n)$。

0 commit comments

Comments
 (0)