返回与给定前序遍历 preorder 相匹配的二叉搜索树(binary search tree)的根结点。
(回想一下,二叉搜索树是二叉树的一种,其每个节点都满足以下规则,对于 node.left 的任何后代,值总 < node.val,而 node.right 的任何后代,值总 > node.val。此外,前序遍历首先显示节点 node 的值,然后遍历 node.left,接着遍历 node.right。)
题目保证,对于给定的测试用例,总能找到满足要求的二叉搜索树。
示例:
输入:[8,5,1,7,10,12]
输出:[8,5,10,1,7,null,12]
提示:
1 <= preorder.length <= 100
1 <= preorder[i] <= 10^8
preorder 中的值互不相同
#include <iostream>
#include <vector>
#include <algorithm>
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) {}
};
class Solution {
public:
TreeNode* bstFromPreorder(vector<int>& preorder) {
vector<int> inorder(preorder);
sort(inorder.begin(), inorder.end());
return buildTree(preorder, inorder);
}
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
if (preorder.empty() || inorder.empty()) {
return NULL;
}
return SetUpTree(preorder, 0, preorder.size() - 1, inorder, 0, inorder.size() - 1);
}
TreeNode* SetUpTree(vector<int>& preorder, int prestart, int preend,
vector<int>& inorder, int instart, int inend) {
TreeNode* root = new TreeNode(preorder[prestart]); /* 建立根节点 */
int pos = findInRoot(preorder[prestart], inorder, instart, inend);
int lSize = pos - instart;
int rSize = inend - pos;
if (lSize > 0)
root->left = SetUpTree(preorder, prestart + 1, prestart + lSize, inorder, instart, instart + lSize - 1);
if (rSize > 0)
root->right = SetUpTree(preorder, prestart + lSize + 1, preend, inorder, inend - rSize + 1, inend);
return root;
}
private:
int findInRoot(int rootval, vector<int>& arr, int inStart, int inEnd) {
for (int i = inStart; i <= inEnd; i++) {
if (arr[i] == rootval)
return i;
}
return -1;
}
};