题目来源
题目描述
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* bstFromPreorder(vector<int>& preorder) {
}
};
题目解析
如果是一个二叉搜索树而且无重复,那么根据先序遍历数组是可以还原出唯一的树出来的,那么如果它有重复值就不唯一了
递归
定义函数process(L,R):从L…R范围是一棵树的先序遍历结果,请建立出整棵树并把头部node返回
class Solution {
TreeNode * process(vector<int>& pre, int L, int R){
if(L > R){
return nullptr;
}
int firstBig = L + 1;
for (; firstBig <= R; firstBig++) {
if(pre[firstBig] > pre[L]){
break;
}
}
TreeNode *head = new TreeNode(pre[L]);
head->left = process(pre, L + 1, firstBig - 1);
head->right = process(pre, firstBig, R);
return head;
}
public:
TreeNode* bstFromPreorder(vector<int>& pre) {
if(pre.empty()){
return nullptr;
}
return process(pre, 0, pre.size() - 1);
}
};
优化:单调栈
class Solution {
TreeNode * process(vector<int>& pre, int L, int R, std::vector<int> &nearBig){
if(L > R){
return nullptr;
}
int firstBig = (nearBig[L] == -1 || nearBig[L] > R) ? R + 1 : nearBig[L];
TreeNode *head = new TreeNode(pre[L]);
head->left = process(pre, L + 1, firstBig - 1, nearBig);
head->right = process(pre, firstBig, R, nearBig);
return head;
}
public:
TreeNode* bstFromPreorder(vector<int>& pre) {
if(pre.empty()){
return nullptr;
}
int N = pre.size();
std::vector<int> nearBig(N, -1);
std::stack<int> stack;
for (int i = 0; i < N; ++i) {
while (!stack.empty() && pre[stack.top()] < pre[i]){
nearBig[stack.top()] = i; stack.pop();
}
stack.push(i);
}
return process(pre, 0, N - 1, nearBig);
}
};
时间复杂度最优,但是常数项还可以再优化,怎么优化呢?使用数组栈来代替STL栈
递归
class Solution {
TreeNode * process(TreeNode *root, int val){
if(root == nullptr){
return new TreeNode(val);
}
if (root->val > val){
root->left = process(root->left, val);
}else{
root->right = process(root->right, val);
}
return root;
}
public:
TreeNode* bstFromPreorder(vector<int>& pre) {
TreeNode *root = nullptr;
for (int i = 0; i < pre.size(); i++){
root = process(root, pre[i]);
}
return root;
}
};