LeetCode-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".

题目大意

给一个字符串,判断该字符串是否是一个经过前序序列化之后的二叉树。

(树结点用整数表示,空结点用‘#’表示,分割符为‘,’)

示例

E1

Input: "9,3,4,#,#,1,#,#,2,#,6,#,#"
Output: true

E2

Input: "1,#"
Output: false

E3

Input: "9,#,#,1"
Output: false

解题思路

用栈来保存结点访问情况,栈中只需保存bool类型,每次遇到两个‘#’类型将栈顶出栈,同时将栈顶的true变为false,若栈顶为false,则代表其左结点以出栈,则将其出栈,直到栈顶为true,并将其改为false。

复杂度分析

时间复杂度:O(N)

空间复杂度:O(N)

代码

class Solution {
public:
    bool isValidSerialization(string preorder) {
        stack<bool> node;
        if(preorder == "#")
            return true;
        
        int i;
        // 遍历字符串
        for(i = 0; i < preorder.length(); ++i) {
            if(preorder[i] == ',')
                continue;
            // 若访问到一个空结点
            else if(preorder[i] == '#') {
                // 若栈为空,则说明该树非法,退出循环
                if(node.empty())
                    break;
                // 若栈顶为true, 将其改为false
                if(node.top()) {
                    node.pop();
                    node.push(false);
                }
                // 否则需要将栈顶的所有的false出栈
                else {
                    node.pop();
                    if(node.empty())
                        break;
                    while(!node.empty() && !node.top()) {
                        node.pop();
                    }
                    if(!node.empty()) {
                        node.pop();
                        node.push(false);
                    }
                    if(node.empty())
                        break;
                }
            }
            // 否则代表访问到结点值
            else {
                int j = i + 1;
                while(j < preorder.length() && preorder[j] != '#' && preorder[j] != ',')
                    ++j;
                node.push(true);
                i = j - 1;
            }
        }
        // 若提前退出循环或栈非空,则代表树非法
        if(i != preorder.length() - 1 || !node.empty())
            return false;
        return true;
    }
};