[Stack] [leetcode] [Medium] 331. Verify the preorder serialization of the binary tree

topic:

One way to serialize a binary tree is to use preorder traversal. When we encounter a non-empty node, we can record the value of this node. If it is an empty node, we can use a tag value record, such as #.


For example, the above binary tree can be serialized into the string "9,3,4,#,#,1,#,#,2,#,6,#,#", where # represents an empty node.

Given a comma-separated sequence, verify that it is the correct preorder serialization of the binary tree. Write a feasible algorithm without reconstructing the tree.

Each comma-separated character is either an integer or a'#' representing a null pointer.

You can think that the input format is always valid, for example it will never contain two consecutive commas, such as "1,,3".

source:

331. Verify the preorder serialization of the binary tree

Problem-solving idea 1: Stack

After reading the question, I was a little confused. I looked at the examples in the question carefully and found that # are all leaf nodes, and the numbers are all non-leaf nodes.

The idea of ​​determination is as follows:

Define a stack to store the number of children of a digital node. The digital node must have 2 children. Loop all nodes:

  • When the node is #, the stack ends if it is empty, otherwise a child is added to the top element of the stack;
  • When the node is a number, if the stack is empty, it will be pushed directly to the stack, otherwise it will be pushed to the stack after adding a child to the top element of the stack;
  • When the top node of the stack has satisfied 2 children, the stack is popped until it is empty or the top node of the stack is not enough for 2 children.

When the stack is empty and there is no node behind, it returns true, other false.

The code is as follows (a bit confusing):

class Solution {
public:
    bool isValidSerialization(string preorder) {
        stack<int> st;
        int i = 0;
        while (i < preorder.size()) {
            char ch = preorder[i];
            while (i < preorder.size() && preorder[i] != ',') i++;
            i++;

            if (ch == '#') {
                if (st.empty()) break;
                // top++
                int t = st.top();
                st.pop();
                st.push(t+1);
            } else {
                // top++
                if (!st.empty()) {
                    int t = st.top();
                    st.pop();
                    st.push(t+1);
                }
                st.push(0);
            }
            bool end = false;
            while (st.top() == 2) {
                st.pop();
                if (st.empty()) {
                    end = true;
                    break;
                }
            }
            if (end) break;
        }
        return st.empty() && i >= preorder.size();
    }
};

Problem-solving idea 2: Use the nature of nodes

Every non-leaf node must have 2 children, so it must be satisfied: the leaf node must have one more than the non-leaf node. In this question, #node is 1 more than number node.

Writing code based on this nature is simple: define the count cnt=1, when # is --, when the number is ++, and when the count is 0, exit, and after exiting, judge whether there are any nodes in the future.

int isValidSerialization(char * preorder){
    int cnt = 1;
    char *p = preorder;
    while (*p != 0) {
        if (*p == '#') {
            cnt--;
        } else {
            cnt++;
        }
        while (*p != 0 && *p != ',') p++;
        if (*p == ',') p++;

        if (cnt == 0) break;
    }

    return cnt == 0 && *p == 0;
}

 

Guess you like

Origin blog.csdn.net/hbuxiaoshe/article/details/114695571