将后序序列看成树,在数组上玩树的深度遍历,关键点在于找到左子树和右子树的切分点,可以使用二分来加速
public class Solution { public boolean VerifySquenceOfBST(int [] sequence) { if(sequence==null||sequence.length==0) return false; int N = sequence.length; int[] res = process(sequence,0,N-1); return res[0] == 1;//0为false,1为true } //返回结果中0:isBST,1:min,2:max //在数组上玩二叉树套路 //需要左右子树返回三个条件,1.自己是否是BST 2.自己的最小值 3.自己的最大值 //但是左子树右子树的切分点j需要二分找出来,找到的是左子树的最右点,如果找不到返回left - 1 //这样左区就变成了[left,j],右区就变成了[j+1,right] public int[] process(int[] sequence,int left,int right){ if(left>right) return null; int isBST = 1,min = sequence[right],max = sequence[right]; //找到比sequence[right]小的最右位置 int pivot = sequence[right]; int leftMax = findLeftMax(sequence,left,right - 1,pivot); int[] leftRes = process(sequence,left,leftMax); int[] rightRes = process(sequence,leftMax+1,right-1); if(leftRes!=null){ isBST = Math.min(isBST,leftRes[0]); if(leftRes[2]>pivot){//左边最大值大于pivot isBST = 0; } min = Math.min(min,leftRes[1]); max = Math.max(max,leftRes[2]); } if(rightRes!=null){ isBST = Math.min(isBST,rightRes[0]); if(rightRes[1]<pivot){//右边最小值小于pivot isBST = 0; } min = Math.min(min,rightRes[1]); max = Math.max(max,rightRes[2]); } return new int[]{isBST,min,max}; } public int findLeftMax(int[] sequence,int left,int right,int pivot){ if(left>right) return left - 1; int target = left - 1; while(left<=right){ int mid = ((right-left)>>>1)+left; if(sequence[mid]<pivot){ target = mid; left = mid + 1;//向右找 }else{ right = mid - 1;//向左找 } } return target; } }