-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.cpp
More file actions
108 lines (91 loc) · 3.29 KB
/
main.cpp
File metadata and controls
108 lines (91 loc) · 3.29 KB
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
// Source: https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal
// Title: Construct Binary Tree from Preorder and Inorder Traversal
// Difficulty: Medium
// Author: Mu Yang <http://muyang.pro>
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 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://assets.leetcode.com/uploads/2021/02/19/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.
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <algorithm>
#include <iterator>
#include <unordered_map>
#include <vector>
using namespace std;
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) {}
};
// pre: [root, left, right]
// in: [left, root, right]
class Solution {
using Iter = vector<int>::const_iterator;
public:
TreeNode *buildTree(vector<int> &preorder, vector<int> &inorder) {
return dfs(preorder.cbegin(), inorder.cbegin(), inorder.cend());
}
private:
TreeNode *dfs(Iter preFirst, Iter inFirst, Iter inLast) {
if (distance(inFirst, inLast) <= 0) return nullptr;
auto rootVal = *(preFirst++);
auto inMid = find(inFirst, inLast, rootVal);
auto leftSize = inMid - inFirst;
auto left = dfs(preFirst, inFirst, inMid);
auto right = dfs(preFirst + leftSize, inMid + 1, inLast);
return new TreeNode(rootVal, left, right);
}
};
// pre: [root, left, right]
// in: [left, root, right]
class Solution2 {
using Iter = vector<int>::const_iterator;
using IterMap = unordered_map<int, Iter>;
public:
TreeNode *buildTree(vector<int> &preorder, vector<int> &inorder) {
auto n = preorder.size();
auto inMap = IterMap();
for (auto it = inorder.cbegin(); it != inorder.cend(); ++it) {
inMap[*it] = it;
}
return dfs(inMap, preorder.cbegin(), inorder.cbegin(), n);
}
private:
TreeNode *dfs(IterMap &inMap, Iter preFirst, Iter inFirst, int size) {
if (size <= 0) return nullptr;
auto rootVal = *preFirst;
++preFirst, --size;
auto inMid = inMap[rootVal];
auto leftSize = inMid - inFirst;
auto left = dfs(inMap, preFirst, inFirst, leftSize);
auto right = dfs(inMap, preFirst + leftSize, inMid + 1, size - leftSize);
return new TreeNode(rootVal, left, right);
}
};