Description#
Given two integer arrays preorder
and inorder
where preorder
is the preorder traversal of a binary tree and inorder
is the inorder traversal of the same tree, construct and return the binary tree.
Example 1:
![](https://spcdn.pages.dev/leetcode/problems/0105.Construct%20Binary%20Tree%20from%20Preorder%20and%20Inorder%20Traversal/images/tree.jpg)
Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
Output: [3,9,20,null,null,15,7]
Example 2:
Input: preorder = [-1], inorder = [-1]
Output: [-1]
Constraints:
1 <= preorder.length <= 3000
inorder.length == preorder.length
-3000 <= preorder[i], inorder[i] <= 3000
preorder
and inorder
consist of unique values.- Each value of
inorder
also appears in preorder
. preorder
is guaranteed to be the preorder traversal of the tree.inorder
is guaranteed to be the inorder traversal of the tree.
Solutions#
Solution 1: Recursion#
The first node $preorder[0]$ in the preorder sequence is the root node. We find the position $i$ of the root node in the inorder sequence, which divides the inorder sequence into the left subtree $inorder[0..i]$ and the right subtree $inorder[i+1..]$.
Through the intervals of the left and right subtrees, we can calculate the number of nodes in the left and right subtrees, assumed to be $m$ and $n$ respectively. Then in the preorder nodes, the $m$ nodes following the root node are the left subtree, and the $n$ nodes after that are the right subtree.
We can solve this recursively.
Preorder traversal: traverse the root node first, then traverse the left and right subtrees; Inorder traversal: traverse the left subtree first, then traverse the root node, and finally traverse the right subtree.
The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the number of nodes in the binary tree.
If the node values given in the problem have duplicates, then we only need to record all the positions where each node value appears, and then recursively construct the tree.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| # 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 buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]:
def dfs(i: int, j: int, n: int):
if n <= 0:
return None
v = preorder[i]
k = d[v]
l = dfs(i + 1, j, k - j)
r = dfs(i + 1 + k - j, k + 1, n - k + j - 1)
return TreeNode(v, l, r)
d = {v: i for i, v in enumerate(inorder)}
return dfs(0, 0, len(preorder))
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
| /**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
private int[] preorder;
private int[] inorder;
private Map<Integer, Integer> d = new HashMap<>();
public TreeNode buildTree(int[] preorder, int[] inorder) {
int n = preorder.length;
this.preorder = preorder;
this.inorder = inorder;
for (int i = 0; i < n; ++i) {
d.put(inorder[i], i);
}
return dfs(0, 0, n);
}
private TreeNode dfs(int i, int j, int n) {
if (n <= 0) {
return null;
}
int v = preorder[i];
int k = d.get(v);
TreeNode l = dfs(i + 1, j, k - j);
TreeNode r = dfs(i + 1 + k - j, k + 1, n - 1 - (k - j));
return new TreeNode(v, l, r);
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
| /**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
int n = preorder.size();
unordered_map<int, int> d;
for (int i = 0; i < n; ++i) {
d[inorder[i]] = i;
}
function<TreeNode*(int, int, int)> dfs = [&](int i, int j, int n) -> TreeNode* {
if (n <= 0) {
return nullptr;
}
int v = preorder[i];
int k = d[v];
TreeNode* l = dfs(i + 1, j, k - j);
TreeNode* r = dfs(i + 1 + k - j, k + 1, n - 1 - (k - j));
return new TreeNode(v, l, r);
};
return dfs(0, 0, n);
}
};
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
| /**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func buildTree(preorder []int, inorder []int) *TreeNode {
d := map[int]int{}
for i, x := range inorder {
d[x] = i
}
var dfs func(i, j, n int) *TreeNode
dfs = func(i, j, n int) *TreeNode {
if n <= 0 {
return nil
}
v := preorder[i]
k := d[v]
l := dfs(i+1, j, k-j)
r := dfs(i+1+k-j, k+1, n-1-(k-j))
return &TreeNode{v, l, r}
}
return dfs(0, 0, len(preorder))
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
| /**
* Definition for a binary tree node.
* class TreeNode {
* val: number
* left: TreeNode | null
* right: TreeNode | null
* constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
* }
*/
function buildTree(preorder: number[], inorder: number[]): TreeNode | null {
const d: Map<number, number> = new Map();
const n = inorder.length;
for (let i = 0; i < n; ++i) {
d.set(inorder[i], i);
}
const dfs = (i: number, j: number, n: number): TreeNode | null => {
if (n <= 0) {
return null;
}
const v = preorder[i];
const k = d.get(v)!;
const l = dfs(i + 1, j, k - j);
const r = dfs(i + 1 + k - j, k + 1, n - 1 - (k - j));
return new TreeNode(v, l, r);
};
return dfs(0, 0, n);
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
| // Definition for a binary tree node.
// #[derive(Debug, PartialEq, Eq)]
// pub struct TreeNode {
// pub val: i32,
// pub left: Option<Rc<RefCell<TreeNode>>>,
// pub right: Option<Rc<RefCell<TreeNode>>>,
// }
//
// impl TreeNode {
// #[inline]
// pub fn new(val: i32) -> Self {
// TreeNode {
// val,
// left: None,
// right: None
// }
// }
// }
use std::rc::Rc;
use std::cell::RefCell;
use std::collections::HashMap;
impl Solution {
pub fn build_tree(preorder: Vec<i32>, inorder: Vec<i32>) -> Option<Rc<RefCell<TreeNode>>> {
let mut d = HashMap::new();
for (i, &x) in inorder.iter().enumerate() {
d.insert(x, i);
}
Self::dfs(&preorder, &d, 0, 0, preorder.len())
}
pub fn dfs(
preorder: &Vec<i32>,
d: &HashMap<i32, usize>,
i: usize,
j: usize,
n: usize
) -> Option<Rc<RefCell<TreeNode>>> {
if n <= 0 {
return None;
}
let v = preorder[i];
let k = d[&v];
let mut root = TreeNode::new(v);
root.left = Self::dfs(preorder, d, i + 1, j, k - j);
root.right = Self::dfs(preorder, d, i + k - j + 1, k + 1, n - k + j - 1);
Some(Rc::new(RefCell::new(root)))
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
| /**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {number[]} preorder
* @param {number[]} inorder
* @return {TreeNode}
*/
var buildTree = function (preorder, inorder) {
const d = new Map();
const n = inorder.length;
for (let i = 0; i < n; ++i) {
d.set(inorder[i], i);
}
const dfs = (i, j, n) => {
if (n <= 0) {
return null;
}
const v = preorder[i];
const k = d.get(v);
const l = dfs(i + 1, j, k - j);
const r = dfs(i + 1 + k - j, k + 1, n - 1 - (k - j));
return new TreeNode(v, l, r);
};
return dfs(0, 0, n);
};
|
Solution 2#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| class Solution:
def getBinaryTrees(self, preOrder: List[int], inOrder: List[int]) -> List[TreeNode]:
def dfs(i: int, j: int, n: int) -> List[TreeNode]:
if n <= 0:
return [None]
v = preOrder[i]
ans = []
for k in d[v]:
if j <= k < j + n:
for l in dfs(i + 1, j, k - j):
for r in dfs(i + 1 + k - j, k + 1, n - 1 - (k - j)):
ans.append(TreeNode(v, l, r))
return ans
d = defaultdict(list)
for i, x in enumerate(inOrder):
d[x].append(i)
return dfs(0, 0, len(preOrder))
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
| /**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
private int[] preorder;
private Map<Integer, Integer> d = new HashMap<>();
public TreeNode buildTree(int[] preorder, int[] inorder) {
int n = preorder.length;
this.preorder = preorder;
for (int i = 0; i < n; ++i) {
d.put(inorder[i], i);
}
return dfs(0, 0, n);
}
private TreeNode dfs(int i, int j, int n) {
if (n <= 0) {
return null;
}
int v = preorder[i];
int k = d.get(v);
TreeNode l = dfs(i + 1, j, k - j);
TreeNode r = dfs(i + 1 + k - j, k + 1, n - 1 - (k - j));
return new TreeNode(v, l, r);
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
| /**
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* };
*/
class Solution {
public:
vector<TreeNode*> getBinaryTrees(vector<int>& preOrder, vector<int>& inOrder) {
int n = inOrder.size();
unordered_map<int, vector<int>> d;
for (int i = 0; i < n; ++i) {
d[inOrder[i]].push_back(i);
}
function<vector<TreeNode*>(int, int, int)> dfs = [&](int i, int j, int n) -> vector<TreeNode*> {
vector<TreeNode*> ans;
if (n <= 0) {
ans.push_back(nullptr);
return ans;
}
int v = preOrder[i];
for (int k : d[v]) {
if (k >= j && k < j + n) {
auto lefts = dfs(i + 1, j, k - j);
auto rights = dfs(i + 1 + k - j, k + 1, n - 1 - (k - j));
for (TreeNode* l : lefts) {
for (TreeNode* r : rights) {
TreeNode* node = new TreeNode(v);
node->left = l;
node->right = r;
ans.push_back(node);
}
}
}
}
return ans;
};
return dfs(0, 0, n);
}
};
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
| func getBinaryTrees(preOrder []int, inOrder []int) []*TreeNode {
n := len(preOrder)
d := map[int][]int{}
for i, x := range inOrder {
d[x] = append(d[x], i)
}
var dfs func(i, j, n int) []*TreeNode
dfs = func(i, j, n int) []*TreeNode {
ans := []*TreeNode{}
if n <= 0 {
ans = append(ans, nil)
return ans
}
v := preOrder[i]
for _, k := range d[v] {
if k >= j && k < j+n {
lefts := dfs(i+1, j, k-j)
rights := dfs(i+1+k-j, k+1, n-1-(k-j))
for _, left := range lefts {
for _, right := range rights {
ans = append(ans, &TreeNode{v, left, right})
}
}
}
}
return ans
}
return dfs(0, 0, n)
}
|