输入一个整数数组,判断该数组是否是某二叉搜索树的后序遍历的结果。若是是则输出Yes,不然输出No。假设输入的数组的任意两个数字都互不相同。数组
每一个测试案例包括2行:测试
第一行为1个整数n(1<=n<=10000),表示数组的长度。spa
第二行包含n个整数,表示这个数组,数组中的数的范围是[0,100000000]。code
对应每一个测试案例,若是输入数组是某二叉搜索树的后序遍历的结果输出Yes,不然输出No。blog
7 5 7 6 9 11 10 8 4 7 4 6 5
Yes No
首先咱们观察题目:二叉搜索树,后序遍历两个知识点。io
二叉搜索树,用于搜索,所以内部节点没有重复的元素。另外,知足二叉树的性质,左子树都比本身小,右子树都比本身大。那么可想而知,若是按照后序遍历,先左后右最后本身的顺序来遍历树,数组的最后一个元素确定是本身(父节点),而后剩余的部分分红两个部分,第一部分都比本身小(左子树部分),第二部分都比本身大(右子树部分),所以套用这个关系就能够循环检验出是不是二叉搜索树的后序遍历了。class
int isPost(int i,int j){ if(i == j) return 1; else{ int k=j-1; while(k>=i){ if(test[k] > test[j]) k--; else break; } int flag = k; while(k>=i){ if(test[k] < test[j]) k--; else break; } if(k == i-1){ if(test[i]>test[j] || test[j-1]<test[j] ){ //printf("(%d-%d)\n",i,j-1); return isPost(i,j-1); }else{ //printf("(%d-%d)(%d-%d)\n",i,flag,flag+1,j-1); return (isPost(i,flag))&&(isPost(flag+1,j-1)); } }else{ return 0; } } }
另外要注意的是,本题的二叉树并不是满二叉树,所以可能出现下面的测试代码:test
3 1 2 3
也就是说,这个树的父节点,只有左子树,没有右子树(右孩子),可是这个测试用例仍然是要经过的。所以须要外加一个判断,判断是否仅有单个孩子子树二叉树
if(test[i]>test[j] || test[j-1]<test[j] ){ //printf("(%d-%d)\n",i,j-1); return isPost(i,j-1); }
#include <stdio.h> #include <stdlib.h> #include <memory.h> int test[10005]={0}; int isPost(int i,int j); int main(){ int n,i; while(scanf("%d",&n)!=EOF){ for(i=0;i<n;i++) scanf("%d",&test[i]); if(isPost(0,n-1)) printf("Yes\n"); else printf("No\n"); } return 0; } int isPost(int i,int j){ if(i == j) return 1; else{ int k=j-1; while(k>=i){ if(test[k] > test[j]) k--; else break; } int flag = k; while(k>=i){ if(test[k] < test[j]) k--; else break; } if(k == i-1){ if(test[i]>test[j] || test[j-1]<test[j] ){ //printf("(%d-%d)\n",i,j-1); return isPost(i,j-1); }else{ //printf("(%d-%d)(%d-%d)\n",i,flag,flag+1,j-1); return (isPost(i,flag))&&(isPost(flag+1,j-1)); } }else{ return 0; } } } /************************************************************** Problem: 1367 User: xhalo Language: C Result: Accepted Time:10 ms Memory:952 kb ****************************************************************/