1.题目描述:
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。
2.解题思路:
链接:https://www.nowcoder.com/questionTerminal/a861533d45854474ac791d90e447bafd
来源:牛客网
采用分治法的思想,找到根结点、左子树的序列、右子树的序列,分别判断左右子序列是否为二叉树的后序序列。
由题意可得:
1. 后序遍历序列的最后一个元素为二叉树的根节点;
2. 二叉搜索树左子树上所有的结点均小于根结点、右子树所有的结点均大于根结点。
3.算法步骤:
- 找到根结点;
- 遍历序列,找到第一个大于等于根结点的元素i,则i左侧为左子树、i右侧为右子树;
- 我们已经知道i左侧所有元素均小于根结点,那么再依次遍历右侧,看是否所有元素均大于根结点;若出现小于根结点的元素,则直接返回false;若右侧全都大于根结点,则:
- 分别递归判断左/右子序列是否为后序序列;
4.代码:
#include<iostream>
#include <vector>
using namespace std;
bool VerifySquenceOfBST(vector<int> sequence)
{
if(sequence.size()==0)
return false;
int root=sequence[sequence.size()-1];
vector<int> seq_left, seq_right;
int i;
for(i=0;sequence[i]<root;i++);
for(int j=0; j<sequence.size()-1;j++)
{
if(j<i)
seq_left.push_back(sequence[j]);
else
seq_right.push_back(sequence[j]);
}
//判断右子树的结点是否都大于根节点
for(int k=0; k<seq_right.size();k++)
{
if(seq_right[k]<root)
return false;
}
//判断左右子树是否为二叉查找树
bool left=true;
if(i>0)
left=VerifySquenceOfBST(seq_left);
bool right=true;
if(i<sequence.size()-1)
right=VerifySquenceOfBST(seq_right);
return left&&right;
}
void Print(vector<int> &myarray)
{
int num=myarray.size();
for(int i=0; i<num;i++)
cout<<myarray[i]<<" ";
cout<<endl;
return;
}
int main()
{
vector<int> vec={5,7,6,9,11,10,8};
Print(vec);
bool a=VerifySquenceOfBST( vec );
cout<< a<<endl;
return 0;
}
5.运行结果:
5 7 6 9 11 10 8
1
Process returned 0 (0x0) execution time : 0.253 s
Press any key to continue.