PROBLEM
剑指 Offer 33. 二叉搜索树的后序遍历序列
难度 中等
MY ANSWER
后序遍历序列最后一个元素为根节点,由二叉搜索树性质可得,序列以第一个比根节点值大的元素为界,左边全部小于根节点值,右边全部大于根节点值,可以通过检查是否符合该情况来判断能否满足二叉搜索树的定义。递归对数组进行遍历,先遍历整个树判断是否符合上述条件,然后是左子树、右子树如此递归。时间复杂度为O(n^2),空间复杂度O(n)。
class Solution { public: vector<int> p; bool judge(int left, int right){ if(left >= right - 1) { return true; } int sign = p[right]; int mid = right; for(int i = left; i < right; i++) { if(p[i] > sign) { mid = i; break; } } for(int i = mid; i < right; i++) { if(p[i] < sign) { return false; } } return judge(left, mid - 1) && judge(mid, right - 1); } bool verifyPostorder(vector<int>& postorder) { p = postorder; return judge(0, p.size() - 1); } };
|
BETTER SOLUTION
基本思想为遍历后序遍历序列的倒序,若出现降序的节点,则该节点的父节点为节点前面升序序列的第一个比它大的节点,且节点右边的所有节点值都应该小于父节点值。
使用单调栈来辅助构造二叉树,root表示父节点值。从末尾往前遍历序列,若值大于root,说明不满足二叉搜索树定义返回false;若栈不为空且值小于栈顶,则将栈顶值赋值给root并出栈,直到栈顶值小于当前值,最后将当前值入栈。若遍历完成,则说明满足二叉搜索树定义返回true。时间复杂度为O(n),空间复杂度O(n)。
class Solution { public: bool verifyPostorder(vector<int>& postorder) { stack<int> s; int root = INT_MAX; for(int i = postorder.size() - 1; i >= 0; i--) { if(postorder[i] > root) { return false; } while(s.size() && s.top() > postorder[i]) { root = s.top(); s.pop(); } s.push(postorder[i]); } return true; } };
|
SUMMARY
重点掌握单调栈在此题中的应用。