1008. 前序遍历构造二叉搜索树
思路
-
方法1
-
二叉搜索树,BST,左子树小于根,右子树大于根,如此递归定义。
-
BST的中序遍历,即按递增排序的序列。
-
如此,通过先序遍历和中序遍历,即可唯一确定一棵树。
-
-
方法2
- 先序遍历,先根,BST,左子树小于根,右子树大于根。
- 递归构造
-
方法3
- 在方法2的基础上,我们直接用区间递归构造即可。
代码
-
方法1
/** * 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 { private: unordered_map<int,int> cnt; public: TreeNode* bstFromPreorder(vector<int>& preorder) { vector<int>inorder(preorder); sort(inorder.begin(),inorder.end()); for(int i=0;i<inorder.size();i++){ cnt[inorder[i]]=i; } return build(preorder, 0, preorder.size()-1, inorder, 0, inorder.size()-1); } TreeNode* build(vector<int>& preorder, int preStart, int preEnd, vector<int>& inorder, int inStart, int inEnd){ if(preStart>preEnd){ return nullptr; } int rootval = preorder[preStart]; int index = cnt[rootval]; int leftsize = index - inStart; TreeNode* root = new TreeNode(rootval); root->left = build(preorder, preStart+1, preStart+leftsize, inorder, inStart, index-1); root->right = build(preorder, preStart+leftsize+1, preEnd, inorder, index+1, inEnd); return root; } };
-
方法2
/** * 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* bstFromPreorder(vector<int>& preorder) { return build(preorder, 0, preorder.size()-1); } TreeNode* build(vector<int>& preorder, int left, int right){ if(left>right) return nullptr; int rootval = preorder[left]; TreeNode* root = new TreeNode(rootval); int l = left, r = right;//如果 l=left+1,对于只有两个数的区间,就会出问题 while(l<r){ int mid = (l+r)/2+1;//保证不会一直 mid=l,陷入死循环 if(preorder[mid] < rootval){ // 中间值小于根,往右边 l = mid; }else{ // 中间值大于根,往左边 r = mid-1;//保证不会一直 mid=r,陷入死循环 } } root->left = build(preorder, left+1, l); root->right = build(preorder, l+1, right); return root; } };
-
方法3
/** * 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 { private: int idx=0;//保证函数内部的修改有效。 public: TreeNode* bstFromPreorder(vector<int>& preorder) { return build(preorder, -1, 1e8+5); } TreeNode* build(vector<int>& preorder, int lower, int higher){ if(idx==preorder.size()){ return nullptr; } int val = preorder[idx]; if(val<lower||val>higher) return nullptr; idx++; TreeNode* root = new TreeNode(val); root->left = build(preorder, lower, val); root->right = build(preorder, val, higher); return root; } };