Method 1: Divide and conquer: time O( n 2 n^2n2 ), space O(n)
answer:
- Using the rules of post-order traversal: left tree | right tree | root node, divide the post-order traversal sequence into sub-trees
- Check whether each subtree satisfies the characteristics of the binary search tree: the left tree is smaller than the root node
- If all are satisfied, the array is correct
- Disadvantage: Only one root node can be detected each time the array is traversed, so checking all root nodes requires O( n 2 n^2n2 ) time
Time: Only one node can be reduced by traversing the array once, and each traversal requires O(n) time.
Space: When the binary tree degenerates into a single tree, it requires O(n) space
class Solution {
public:
bool verifyPostorder(vector<int>& postorder)
{
// 1.后序遍历的规则:左支|右支|根节点
// 2.因此只要满足每颗树都满足二叉搜索树的特性,则说明该数组正确
// 3.利用分治思想将二叉树划分成一颗颗子树
// 4.缺点:每次检查都要遍历二叉树,且一遍只能检查完成一个节点的正确性,时间复杂度O(n^2)
return CheckTree(postorder, 0, postorder.size());
}
bool CheckTree(vector<int>& postorder, int left, int right)
{
if (left >= right)
return true;
int i = left;
while (postorder[i] < postorder[right - 1])
i++;
int pos = i;
while (postorder[i] > postorder[right - 1])
i++;
return (i == right - 1) && CheckTree(postorder, left, pos) && CheckTree(postorder, pos, right - 1);
}
};
Method 2: Monotonic stack: time O(n), space O(n)
answer:
- Reverse order of post-order traversal: root node | right tree | left tree
- Use a stack to store the left tree of the search tree, which is a node smaller than the root node
- As long as the stack is not empty, and it is detected that the current node is smaller than the top element of the stack, it means that a left subtree of the root node subtree has been reached
- Keep popping the stack until the stack is empty or the top element of the stack is greater than the current node
- The root node is the last popped element
Note: The first root node can be regarded as the left subtree of INT_MAX, and the right subtree is empty
Time: All nodes are pushed and popped once, so it is O(n)
space: single tree space O(n)
class Solution {
public:
bool verifyPostorder(vector<int>& postorder)
{
// 1.单调栈:借助一个栈结构专门存储搜索树的右子树,也就是比根节点大的树
// 2.只要栈不空,并且检测到当前节点比栈顶元素小,则说明到达了左子树
// 3.一直出栈,直到栈空 或者 栈顶元素小于当前节点
// 4.根节点为最后一次出栈元素
stack<int> stc;
int root = INT_MAX;
for (int i = postorder.size() - 1; i >= 0; --i)
{
if (postorder[i] > root)
return false;
while (!stc.empty() && stc.top() > postorder[i])
{
root = stc.top();
stc.pop();
}
stc.push(postorder[i]);
}
return true;
}
};