[Jianzhi 33] Post-order traversal sequence of binary search tree

Method 1: Divide and conquer: time O( n 2 n^2n2 ), space O(n)

answer:

  1. Using the rules of post-order traversal: left tree | right tree | root node, divide the post-order traversal sequence into sub-trees
  2. Check whether each subtree satisfies the characteristics of the binary search tree: the left tree is smaller than the root node
  3. If all are satisfied, the array is correct
  4. 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)

Insert picture description here

answer:

  1. Reverse order of post-order traversal: root node | right tree | left tree
  2. Use a stack to store the left tree of the search tree, which is a node smaller than the root node
  3. 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
  4. Keep popping the stack until the stack is empty or the top element of the stack is greater than the current node
  5. 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;
    }
};

Guess you like

Origin blog.csdn.net/qq_45691748/article/details/114263696