构建搜索二叉树+后序遍历
- 构建搜索二叉树->后序遍历->比较顺序
- 搜索二叉树的结构和后序遍历是一一对应的,通过逆后序遍历可以重新构建唯一的二叉树。
class Solution {
public:
void buildTree(TreeNode* cur,TreeNode* front,int val)
{
if(!cur)
{
if(front->val<val)
{
front->right=new TreeNode(val);
}
else{
front->left=new TreeNode(val);
}
return;
}
else if(cur->val>val)
{
buildTree(cur->left, cur, val);
}
else{
buildTree(cur->right,cur,val);
}
}
int k=0;
void Order(TreeNode* root,vector<int>& sequence)
{
if(!root)
{
return ;
}
Order(root->left,sequence);
Order(root->right,sequence);
if(root->val==sequence[k])
{
k++;
}
}
bool VerifySquenceOfBST(vector<int> sequence) {
if(!sequence.size())
{
return false;
}
TreeNode* root=new TreeNode(sequence[sequence.size()-1]);
TreeNode* cur=root;
for(int i=sequence.size()-2;i>=0;i--) //n^2
{
cur=root;
buildTree(cur,nullptr,sequence[i]);
}
//后序遍历
Order(root,sequence);
return k==sequence.size();
}
};
单调栈
- 由于搜索二叉树的性质,倒序时,存在如果sequence[i]>sequence[i+1],说明sequence[i]是右节点,反之说明sequence[i]为左节点,此时进入左子树,sequence[i]到sequence[0]都小于满足小于root节点的值。
- root可能为sequence[i]/sequence的父/祖先节点,root节点的获取用栈保存,栈保存每一个节点遍历的值。
- 单独栈应用于有明确的大小关系,栈保存每一个遍历的节点值,而不需要时再弹出,省去了分辨root节点的逻辑。
#include <climits>
class Solution {
public:
bool VerifySquenceOfBST(vector<int> sequence) {
if(sequence.empty())
{
return false;
}
int root=INT_MAX;
stack<int> s;
for(int i=sequence.size()-1;i>=0;i--)
{
if(sequence[i]>root)
return false;
while(!s.empty()&&s.top()>sequence[i])
{
root=s.top();
s.pop();
}
s.push(sequence[i]);
}
return true;
}
};
递归法
- 搜索二叉树可以根据后序遍历重构出
- 转化成递归问题,其中第一个判断的for中要注意一定要break跳出,不然在会导致r1不更新
class Solution {
public:
bool order(vector<int>& sequence,int l,int r)
{
if(l>=r)
{
return true;
}
//找出中间节点
int root =sequence[r];
int r1=l;
for(int i=l;i<=r;i++)
{
if(sequence[i]>=root)
{
r1=i;
break;
}
}
//i为新l
for(int i=r1;i<=r-1;i++)
{
if(sequence[i]<root) return false;
}
return order(sequence,l,r1-1)&&order(sequence, r1, r-1);
}
bool VerifySquenceOfBST(vector<int> sequence) {
//
if(sequence.empty()) return false;
return order(sequence,0,sequence.size()-1);
}
};