【Jianzhi 33】Post-order traversal of binary search tree

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

Problem-solving ideas:

  • Using the characteristics of post-order traversal: left tree | right tree | root node, check whether the left and right subtrees of each root meet the characteristics of the binary search tree
  • If the current root node meets the characteristics of the search tree, continue to check in the left and right subtrees of the node

answer:

  • Recursive divide-and-conquer method: define a root node and traverse the array until the node value is greater than the root node.
  • Record the current position pos, and continue to traverse backwards. The subsequent nodes should satisfy that all nodes are greater than the root node.
  • Divide and conquer: Check the trees on both sides of the pos position, which is divided into left and right trees
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);
    } 
};

Time complexity: Each round of traversal can only reduce one node, and each round must traverse the array, so it needs O( n 2 n^2n2 )
Space complexity: recursive call, when the binary tree is a single tree, it needs O(n) space

Method 2: Monotonic stack: time O(n), space O(n)

Problem-solving ideas:

  • Reverse order of post-order traversal: root node | right tree | left tree, use this feature to check the right tree of each root first
  • With the help of a stack structure, the right tree of the root node is saved. When the node is smaller than the top element of the stack, it means that you have come to the left tree of a subtree
  • So keep popping the stack until the top element of the stack is smaller than the current node, or the stack is empty
  • The last popped element is the root node of the new tree
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;
    }
};

Time: O(n)
space is required to traverse all nodes: O(n) space is required for a single tree

Guess you like

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