23.二叉搜索树的后序遍历序列
题目描述
思路:
1 class Solution { 2 3 public boolean verifyPostorder(int[] postorder) { 4 5 return helpVerifyPostorder(postorder, 0, postorder.length - 1); 6 } 7 8 // 辅助函数,判断数组的某个区间是否符合后序遍历序列 9 public boolean helpVerifyPostorder(int[] postorder, int left, int right){ 10 if(right - left <= 1){ // 任意两个数都能构成搜索树的后序遍历序列 11 return true; 12 } 13 // 找到右边界作为根节点 14 // 左边界开始遍历数组,找到第一个大于根节点的元素,这前半段元素作为左子树 15 int mid = left; 16 for(mid = left; mid < right && postorder[mid] < postorder[right]; mid++); 17 18 // 继续遍历右半段数组,判断是否所有元素都大于根节点 19 // 如果都大于,则右半段作为右子树,否则直接返回false 20 for(int i = mid; mid < right; mid++){ 21 if(postorder[mid] < postorder[right]){ 22 return false; 23 } 24 } 25 26 // 递归判断左右子树 27 return helpVerifyPostorder(postorder, left, mid - 1) && helpVerifyPostorder(postorder, mid, right - 1); 28 } 29 }
leetcode运行时间为2ms, 空间为36.3MB
复杂度分析:
时间复杂度:其实这个思路过程有点像快速排序的过程,都是对一个区间的数组选定某元素作为主元后,根据主元将该区间的所有元素划分为左右集合,最终继续递归左右集合,所以这个算法复杂度也和快速排序复杂度比较像,都是O(nlogn), 但是当前算法的思路有一个剪枝的过程,如果再判断右子区间的元素存在小于根节点的,说明整棵树不是二叉树的后序遍历序列,直接返回false, 所以该算法的时间复杂度可能会比快速排序的时间复杂度好一些。
空间复杂度:取决于递归栈的深度,栈的深度取决于数组对应的数的高度,树高最大为O(n), 最小为O(logn), 所以空间复杂度最大为O(n), 最小为O(logn)
还有一种单调栈的方式,但是不太看得懂
先把题解贴一下,以后有时间再来看:https://leetcode-cn.com/problems/er-cha-sou-suo-shu-de-hou-xu-bian-li-xu-lie-lcof/solution/dan-diao-di-zeng-zhan-by-shi-huo-de-xia-tian/
使用单调栈记录和更新余下元素的上界,然后检查是否存在不符合上界约束的元素。