Skip to content

Commit 4e51c3a

Browse files
committedFeb 13, 2022
feat: update solutions to lcof problem: No.07
面试题07.重建二叉树
1 parent 31995c5 commit 4e51c3a

File tree

9 files changed

+185
-185
lines changed

9 files changed

+185
-185
lines changed
 

‎lcof/面试题06. 从尾到头打印链表/README.md

+22-19
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,36 @@
22

33
## 题目描述
44

5-
输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。
5+
<p>输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。</p>
66

7-
**示例 1:**
7+
<p>&nbsp;</p>
88

9-
```
10-
输入:head = [1,3,2]
11-
输出:[2,3,1]
12-
```
9+
<p><strong>示例 1:</strong></p>
10+
11+
<pre><strong>输入:</strong>head = [1,3,2]
12+
<strong>输出:</strong>[2,3,1]</pre>
1313

14-
**限制:**
14+
<p>&nbsp;</p>
1515

16-
- `0 <= 链表长度 <= 10000`
16+
<p><strong>限制:</strong></p>
17+
18+
<p><code>0 &lt;= 链表长度 &lt;= 10000</code></p>
1719

1820
## 解法
1921

2022
该题需要将链表转换为数组,且需要反向。由于目标是链表,无法第一时间得知长度,声明等长数组。
2123

2224
解题方案:
23-
- 遍历
24-
- 从头到尾遍链表,获取链表长度,声明等长数组;
25-
- 再次遍历并放入数组当中,在数组中的放置顺序是从尾到头。
26-
- 递归
27-
- 记录深度,递归到链表尾部;
28-
- 将深度化为数组长度,将回溯结果正序放入数组当中。
29-
- 动态数组
30-
- 遍历链表,将元素放入数组当中;
31-
- 遍历结束,将数组倒置后返回(`reverse()`)。
25+
26+
- 遍历
27+
- 从头到尾遍链表,获取链表长度,声明等长数组;
28+
- 再次遍历并放入数组当中,在数组中的放置顺序是从尾到头。
29+
- 递归
30+
- 记录深度,递归到链表尾部;
31+
- 将深度化为数组长度,将回溯结果正序放入数组当中。
32+
- 动态数组
33+
- 遍历链表,将元素放入数组当中;
34+
- 遍历结束,将数组倒置后返回(`reverse()`)。
3235

3336
<!-- tabs:start -->
3437

@@ -230,7 +233,7 @@ function reversePrint(head: ListNode | null): number[] {
230233
// pub val: i32,
231234
// pub next: Option<Box<ListNode>>
232235
// }
233-
//
236+
//
234237
// impl ListNode {
235238
// #[inline]
236239
// fn new(val: i32) -> Self {
@@ -263,7 +266,7 @@ impl Solution {
263266
// pub val: i32,
264267
// pub next: Option<Box<ListNode>>
265268
// }
266-
//
269+
//
267270
// impl ListNode {
268271
// #[inline]
269272
// fn new(val: i32) -> Self {

‎lcof/面试题07. 重建二叉树/README.md

+96-90
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,46 @@
22

33
## 题目描述
44

5-
输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
5+
<p>输入某二叉树的前序遍历和中序遍历的结果,请构建该二叉树并返回其根节点。</p>
66

7-
例如,给出
7+
<p>假设输入的前序遍历和中序遍历的结果中都不含重复的数字。</p>
88

9-
```
10-
前序遍历 preorder = [3,9,20,15,7]
11-
中序遍历 inorder = [9,3,15,20,7]
12-
```
9+
<p> </p>
1310

14-
返回如下的二叉树:
11+
<p><strong>示例 1:</strong></p>
12+
<img alt="" src="https://cdn.jsdelivr.net/gh/doocs/leetcode@main/lcof/%E9%9D%A2%E8%AF%95%E9%A2%9807.%20%E9%87%8D%E5%BB%BA%E4%BA%8C%E5%8F%89%E6%A0%91/images/tree.jpg" />
13+
<pre>
14+
<strong>Input:</strong> preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
15+
<strong>Output:</strong> [3,9,20,null,null,15,7]
16+
</pre>
1517

16-
```
17-
3
18-
/ \
19-
9 20
20-
/ \
21-
15 7
22-
```
18+
<p><strong>示例 2:</strong></p>
19+
20+
<pre>
21+
<strong>Input:</strong> preorder = [-1], inorder = [-1]
22+
<strong>Output:</strong> [-1]
23+
</pre>
24+
25+
<p> </p>
26+
27+
<p><strong>限制:</strong></p>
28+
29+
<p><code>0 <= 节点个数 <= 5000</code></p>
2330

24-
**限制:**
31+
<p> </p>
2532

26-
- `0 <= 节点个数 <= 5000`
33+
<p><strong>注意</strong>:本题与主站 105 题重复:<a href="https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/">https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/</a></p>
2734

2835
## 解法
2936

37+
前序序列的第一个结点 `preorder[0]` 为根节点,我们在中序序列中找到根节点的位置 i,可以将中序序列划分为左子树 `inorder[:i]` 、右子树 `inorder[i+1:]`
38+
39+
通过左右子树的区间,可以计算出左、右子树节点的个数,假设为 m、n。然后在前序节点中,从根节点往后的 m 个节点为左子树,再往后的 n 个节点为右子树。
40+
41+
递归求解即可。
42+
43+
> 前序遍历:先遍历根节点,再遍历左右子树;中序遍历:先遍历左子树,再遍历根节点,最后遍历右子树。
44+
3045
<!-- tabs:start -->
3146

3247
### **Python3**
@@ -40,21 +55,15 @@
4055
# self.right = None
4156

4257
class Solution:
43-
indexes = {}
4458
def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
45-
def build(preorder, inorder, p1, p2, i1, i2) -> TreeNode:
46-
if p1 > p2 or i1 > i2:
47-
return None
48-
root_val = preorder[p1]
49-
pos = self.indexes[root_val]
50-
root = TreeNode(root_val)
51-
root.left = None if pos == i1 else build(preorder, inorder, p1 + 1, p1 - i1 + pos, i1, pos - 1)
52-
root.right = None if pos == i2 else build(preorder, inorder, p1 - i1 + pos + 1, p2, pos + 1, i2)
53-
return root
54-
n = len(inorder)
55-
for i in range(n):
56-
self.indexes[inorder[i]] = i
57-
return build(preorder, inorder, 0, n - 1, 0, n - 1)
59+
if not preorder:
60+
return None
61+
v = preorder[0]
62+
root = TreeNode(val=v)
63+
i = inorder.index(v)
64+
root.left = self.buildTree(preorder[1:1 + i], inorder[:i])
65+
root.right = self.buildTree(preorder[1 + i:], inorder[i + 1:])
66+
return root
5867
```
5968

6069
### **Java**
@@ -73,21 +82,22 @@ class Solution {
7382
private Map<Integer, Integer> indexes = new HashMap<>();
7483

7584
public TreeNode buildTree(int[] preorder, int[] inorder) {
76-
int n = inorder.length;
77-
for (int i = 0; i < n; ++i) {
85+
for (int i = 0; i < inorder.length; ++i) {
7886
indexes.put(inorder[i], i);
7987
}
80-
return build(preorder, inorder, 0, n - 1, 0, n - 1);
88+
return dfs(preorder, inorder, 0, 0, preorder.length);
8189
}
8290

83-
private TreeNode build(int[] preorder, int[] inorder, int p1, int p2, int i1, int i2) {
84-
if (p1 > p2 || i1 > i2) return null;
85-
int rootVal = preorder[p1];
86-
int pos = indexes.get(rootVal);
87-
TreeNode node = new TreeNode(rootVal);
88-
node.left = pos == i1 ? null : build(preorder, inorder, p1 + 1, pos - i1 + p1, i1, pos - 1);
89-
node.right = pos == i2 ? null : build(preorder, inorder, pos - i1 + p1 + 1, p2, pos + 1, i2);
90-
return node;
91+
private TreeNode dfs(int[] preorder, int[] inorder, int i, int j, int n) {
92+
if (n <= 0) {
93+
return null;
94+
}
95+
int v = preorder[i];
96+
int k = indexes.get(v);
97+
TreeNode root = new TreeNode(v);
98+
root.left = dfs(preorder, inorder, i + 1, j, k - j);
99+
root.right = dfs(preorder, inorder, i + 1 + k - j, k + 1, n - k + j - 1);
100+
return root;
91101
}
92102
}
93103
```
@@ -108,25 +118,13 @@ class Solution {
108118
* @return {TreeNode}
109119
*/
110120
var buildTree = function (preorder, inorder) {
111-
if (!preorder || !preorder.length) return null;
112-
let preIdx = 0;
113-
let inMap = {};
114-
for (let i = 0; i < inorder.length; i++) {
115-
inMap[inorder[i]] = i;
116-
}
117-
function func(start, end) {
118-
if (start > end) {
119-
return null;
120-
}
121-
let preVal = preorder[preIdx];
122-
preIdx++;
123-
let inIdx = inMap[preVal];
124-
let node = new TreeNode(preVal);
125-
node.left = func(start, inIdx - 1);
126-
node.right = func(inIdx + 1, end);
127-
return node;
128-
}
129-
return func(0, preorder.length - 1);
121+
if (preorder.length == 0) return null;
122+
const v = preorder[0];
123+
const root = new TreeNode(v);
124+
const i = inorder.indexOf(v);
125+
root.left = buildTree(preorder.slice(1, 1 + i), inorder.slice(0, i));
126+
root.right = buildTree(preorder.slice(1 + i), inorder.slice(1 + i));
127+
return root;
130128
};
131129
```
132130

@@ -142,47 +140,55 @@ var buildTree = function (preorder, inorder) {
142140
* }
143141
*/
144142
func buildTree(preorder []int, inorder []int) *TreeNode {
145-
return helper(preorder, inorder, 0, 0, len(preorder)-1)
146-
}
147-
148-
func helper(preorder, inorder []int, index, start, end int) *TreeNode {
149-
if start > end {
150-
return nil
151-
}
152-
root := &TreeNode{Val:preorder[index]}
153-
j := start
154-
for j < end && preorder[index] != inorder[j] {
155-
j++
156-
}
157-
root.Left = helper(preorder, inorder, index + 1, start, j - 1)
158-
root.Right = helper(preorder, inorder, index + 1 + j -start, j + 1, end)
159-
return root
143+
indexes := make(map[int]int)
144+
for i, v := range inorder {
145+
indexes[v] = i
146+
}
147+
var dfs func(i, j, n int) *TreeNode
148+
dfs = func(i, j, n int) *TreeNode {
149+
if n <= 0 {
150+
return nil
151+
}
152+
v := preorder[i]
153+
k := indexes[v]
154+
root := &TreeNode{Val: v}
155+
root.Left = dfs(i+1, j, k-j)
156+
root.Right = dfs(i+1+k-j, k+1, n-k+j-1)
157+
return root
158+
}
159+
return dfs(0, 0, len(inorder))
160160
}
161161
```
162162

163163
### **C++**
164164

165165
```cpp
166+
/**
167+
* Definition for a binary tree node.
168+
* struct TreeNode {
169+
* int val;
170+
* TreeNode *left;
171+
* TreeNode *right;
172+
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
173+
* };
174+
*/
166175
class Solution {
167176
public:
177+
unordered_map<int, int> indexes;
178+
168179
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
169-
return build(preorder, inorder, 0, preorder.size() - 1, 0, inorder.size() - 1);
180+
for (int i = 0; i < inorder.size(); ++i) indexes[inorder[i]] = i;
181+
return dfs(preorder, inorder, 0, 0, inorder.size());
170182
}
171183

172-
private:
173-
TreeNode* build(vector<int>& preorder, vector<int>& inorder, int pre_l, int pre_r, int in_l, int in_r) {
174-
if (pre_l > pre_r || in_l > in_r) {
175-
return NULL;
176-
}
177-
int root = preorder[pre_l];
178-
int i = in_l;
179-
while (i <= in_r && inorder[i] != root) {
180-
++i;
181-
}
182-
TreeNode* node = new TreeNode(root);
183-
node->left = build(preorder, inorder, pre_l + 1, pre_l + i - in_l, in_l, i - 1);
184-
node->right = build(preorder, inorder, pre_l + i - in_l + 1, pre_r, i + 1, in_r);
185-
return node;
184+
TreeNode* dfs(vector<int>& preorder, vector<int>& inorder, int i, int j, int n) {
185+
if (n <= 0) return nullptr;
186+
int v = preorder[i];
187+
int k = indexes[v];
188+
TreeNode* root = new TreeNode(v);
189+
root->left = dfs(preorder, inorder, i + 1, j, k - j);
190+
root->right = dfs(preorder, inorder, i + 1 + k - j, k + 1, n - k + j - 1);
191+
return root;
186192
}
187193
};
188194
```
+22-16
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,28 @@
1+
/**
2+
* Definition for a binary tree node.
3+
* struct TreeNode {
4+
* int val;
5+
* TreeNode *left;
6+
* TreeNode *right;
7+
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
8+
* };
9+
*/
110
class Solution {
211
public:
12+
unordered_map<int, int> indexes;
13+
314
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
4-
return build(preorder, inorder, 0, preorder.size() - 1, 0, inorder.size() - 1);
15+
for (int i = 0; i < inorder.size(); ++i) indexes[inorder[i]] = i;
16+
return dfs(preorder, inorder, 0, 0, inorder.size());
517
}
618

7-
private:
8-
TreeNode* build(vector<int>& preorder, vector<int>& inorder, int pre_l, int pre_r, int in_l, int in_r) {
9-
if (pre_l > pre_r || in_l > in_r) {
10-
return NULL;
11-
}
12-
int root = preorder[pre_l];
13-
int i = in_l;
14-
while (i <= in_r && inorder[i] != root) {
15-
++i;
16-
}
17-
TreeNode* node = new TreeNode(root);
18-
node->left = build(preorder, inorder, pre_l + 1, pre_l + i - in_l, in_l, i - 1);
19-
node->right = build(preorder, inorder, pre_l + i - in_l + 1, pre_r, i + 1, in_r);
20-
return node;
19+
TreeNode* dfs(vector<int>& preorder, vector<int>& inorder, int i, int j, int n) {
20+
if (n <= 0) return nullptr;
21+
int v = preorder[i];
22+
int k = indexes[v];
23+
TreeNode* root = new TreeNode(v);
24+
root->left = dfs(preorder, inorder, i + 1, j, k - j);
25+
root->right = dfs(preorder, inorder, i + 1 + k - j, k + 1, n - k + j - 1);
26+
return root;
2127
}
22-
};
28+
};

0 commit comments

Comments
 (0)