Skip to content

Commit d1f1366

Browse files
add solution 1008
1 parent 1a79253 commit d1f1366

File tree

3 files changed

+139
-0
lines changed

3 files changed

+139
-0
lines changed
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
## 先序遍历构造二叉树
2+
3+
### 问题描述
4+
5+
返回与给定先序遍历 **preorder** 相匹配的二叉搜索树(binary **search** tree)的根结点。
6+
7+
**示例1:**
8+
9+
```
10+
输入:[8,5,1,7,10,12]
11+
输出:[8,5,10,1,7,null,12]
12+
```
13+
14+
![示例1](/img/Construct-Binary-Search-Tree-from-Preorder-Traversal.png)
15+
16+
**提示:**
17+
18+
- `1 <= preorder.length <= 100`
19+
- The values of `preorder` are distinct.
20+
21+
### 解法
22+
23+
二叉树类的题目可以考虑使用递归中的分治法,让本次递归的根节点(sub-root)来管理自身子树的生成方式。而本题使用的是**前序遍历法**所生成的数组,则先检查了根节点,再检查左子树,再检查右子树。因此每层递归我们需要确定的是:
24+
25+
* 本层递归的根节点是什么?
26+
* 根节点确定后,本层递归之后的左子树范围是什么,右子树的范围是什么?
27+
28+
对于第一个问题,我们知道前序遍历法的根节点一定是当前范围内的第一个元素;而对于第二个问题,我们知道右子树开始于**第一个比当前根节点大的元素**,而左子树结束于该元素的前面一个元素。在解决了这两个问题后,答案已经比较明确了,在每一层递归中,我们需要一个 start 和一个 end 来表示当前的递归所涉及的元素范围:
29+
30+
* 确定当前的递归是否结束(start > end || start >= end)
31+
* 确定当前递归层的根节点(start)
32+
* 确定左子树的范围(start + 1, leftEnd - 1)和右子树的范围(leftEnd, end)
33+
34+
因此有如下的递归解法:
35+
36+
```java
37+
/**
38+
* Definition for a binary tree node.
39+
* public class TreeNode {
40+
* int val;
41+
* TreeNode left;
42+
* TreeNode right;
43+
* TreeNode(int x) { val = x; }
44+
* }
45+
*/
46+
class Solution {
47+
public TreeNode bstFromPreorder(int[] preorder) {
48+
if (preorder == null || preorder.length == 0) {
49+
return null;
50+
}
51+
// 进入分治法的递归
52+
return helper(preorder, 0, preorder.length - 1);
53+
}
54+
55+
private TreeNode helper(int[] preorder, int start, int end) {
56+
// System.out.println("start: " + start + " end: " + end);
57+
// 确认递归结束的标志,当 start == end 时,表示该区间只剩下一个 subRoot 节点
58+
if (start > end) {
59+
return null;
60+
}
61+
if (start == end) {
62+
return new TreeNode(preorder[start]);
63+
}
64+
// 前序遍历,首先遍历到的为根
65+
TreeNode root = new TreeNode(preorder[start]);
66+
int leftEnd = start;
67+
while (leftEnd <= end) {
68+
if (preorder[leftEnd] > preorder[start]) {
69+
break;
70+
}
71+
leftEnd++;
72+
}
73+
// System.out.println("leftEnd:" + leftEnd + " num: " + preorder[leftEnd]);
74+
root.left = helper(preorder, start + 1, leftEnd - 1);
75+
root.right = helper(preorder, leftEnd, end);
76+
return root;
77+
}
78+
}
79+
```
80+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
{\rtf1\ansi\ansicpg936\cocoartf1671\cocoasubrtf200
2+
{\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\fnil\fcharset134 PingFangSC-Regular;}
3+
{\colortbl;\red255\green255\blue255;}
4+
{\*\expandedcolortbl;;}
5+
\margl1440\margr1440\vieww10800\viewh8400\viewkind0
6+
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0
7+
8+
\f0\fs24 \cf0 /**\
9+
* Definition for a binary tree node.\
10+
* public class TreeNode \{\
11+
* int val;\
12+
* TreeNode left;\
13+
* TreeNode right;\
14+
* TreeNode(int x) \{ val = x; \}\
15+
* \}\
16+
*/\
17+
class Solution \{\
18+
public TreeNode bstFromPreorder(int[] preorder) \{\
19+
if (preorder == null || preorder.length == 0) \{\
20+
return null;\
21+
\}\
22+
//
23+
\f1 \'bd\'f8\'c8\'eb\'b7\'d6\'d6\'ce\'b7\'a8\'b5\'c4\'b5\'dd\'b9\'e9
24+
\f0 \
25+
return helper(preorder, 0, preorder.length - 1);\
26+
\}\
27+
\
28+
private TreeNode helper(int[] preorder, int start, int end) \{\
29+
// System.out.println("start: " + start + " end: " + end);\
30+
//
31+
\f1 \'c8\'b7\'c8\'cf\'b5\'dd\'b9\'e9\'bd\'e1\'ca\'f8\'b5\'c4\'b1\'ea\'d6\'be\'a3\'ac\'b5\'b1
32+
\f0 start == end
33+
\f1 \'ca\'b1\'a3\'ac\'b1\'ed\'ca\'be\'b8\'c3\'c7\'f8\'bc\'e4\'d6\'bb\'ca\'a3\'cf\'c2\'d2\'bb\'b8\'f6
34+
\f0 subRoot
35+
\f1 \'bd\'da\'b5\'e3
36+
\f0 \
37+
if (start > end) \{\
38+
return null;\
39+
\}\
40+
if (start == end) \{\
41+
return new TreeNode(preorder[start]);\
42+
\}\
43+
//
44+
\f1 \'c7\'b0\'d0\'f2\'b1\'e9\'c0\'fa\'a3\'ac\'ca\'d7\'cf\'c8\'b1\'e9\'c0\'fa\'b5\'bd\'b5\'c4\'ce\'aa\'b8\'f9
45+
\f0 \
46+
TreeNode root = new TreeNode(preorder[start]);\
47+
int leftEnd = start;\
48+
while (leftEnd <= end) \{\
49+
if (preorder[leftEnd] > preorder[start]) \{\
50+
break;\
51+
\}\
52+
leftEnd++;\
53+
\}\
54+
// System.out.println("leftEnd:" + leftEnd + " num: " + preorder[leftEnd]);\
55+
root.left = helper(preorder, start + 1, leftEnd - 1);\
56+
root.right = helper(preorder, leftEnd, end);\
57+
return root;\
58+
\}\
59+
\}}

0 commit comments

Comments
 (0)