331. Verify Preorder Serialization of a Binary Tree -- 判断是否为合法的先序序列

One way to serialize a binary tree is to use pre-order traversal. When we encounter a non-null node, we record the node's value. If it is a null node, we record using a sentinel value such as #.

     _9_
    /   
   3     2
  /    / 
 4   1  #  6
/  /    / 
# # # #   # #

For example, the above binary tree can be serialized to the string "9,3,4,#,#,1,#,#,2,#,6,#,#", where # represents a null node.

Given a string of comma separated values, verify whether it is a correct preorder traversal serialization of a binary tree. Find an algorithm without reconstructing the tree.

Each comma separated value in the string must be either an integer or a character '#' representing null pointer.

You may assume that the input format is always valid, for example it could never contain two consecutive commas such as "1,,3".

Example 1:
"9,3,4,#,#,1,#,#,2,#,6,#,#"
Return true

Example 2:
"1,#"
Return false

Example 3:
"9,#,#,1"
Return false

1. 栈

class Solution {
public:
    bool isValidSerialization(string preorder) {
        stack<char> stk;
        bool isNum = false;
        preorder.push_back(','); // dummy tail

        for(auto c: preorder){
            if(c == '#'){
                // absorb: search for pattern `#, number` backward
                while(!stk.empty() && stk.top() == '#'){ 
                    stk.pop(); // pop `#`
                    if(stk.empty() || stk.top() == '#') return false; // pattern `#,#,#`
                    stk.pop(); // pop `number`
                }
                stk.push('#'); // replace `number` with `#` since it has been fully explored/validated
            }else if(c == ','){
                if(isNum) stk.push('n'); // indicate this is a number instead of using the real number
                isNum = false;
            }else{
                isNum = true;
            }
        }

        return stk.size() == 1 && stk.top() == '#';
    }
};

2. 不用栈

class Solution {
public:
    bool isValidSerialization(string preorder) {
        string& s = preorder;
        while (s.size() >= 5) {
            bool find_pattern = false;
            for (int i = s.size()-1; i>= 4; i--) {
                if (s[i] == '#' && s[i-2] == '#' && s[i-4] != '#') {
                    find_pattern = true;
                    int j = i-4-1;
                    /* find the start place of pattern */
                    while (j > 0 && s[j] != ',') j--; 
                    s.replace(j+1, i-j, "#"); /* replace s[j+1, i]  to "#" */
                    break;  /* start a trun search from the end */
                }
            }
            if (!find_pattern) break;
        }

        /* boundary: empty tree */
        return (s.size() == 1 && s[0] == '#');
    }
};

从右向左,若出现(数字,#,#)模式,则替换成一个#。最后若只剩一个#则合法,否则不合法。

原文地址:https://www.cnblogs.com/argenbarbie/p/5418352.html