Leetcode每日一题 331. 验证二叉树的前序序列化

331. 验证二叉树的前序序列化

序列化二叉树的一种方法是使用前序遍历。当我们遇到一个非空节点时,我们可以记录下这个节点的值。如果它是一个空节点,我们可以使用一个标记值记录,例如 #
     _9_
    /   
   3     2
  /    / 
 4   1  #  6
/  /    / 
# # # #   # #

例如,上面的二叉树可以被序列化为字符串 "9,3,4,#,#,1,#,#,2,#,6,#,#",其中 # 代表一个空节点。

给定一串以逗号分隔的序列,验证它是否是正确的二叉树的前序序列化。编写一个在不重构树的条件下的可行算法。

每个以逗号分隔的字符或为一个整数或为一个表示 null 指针的 '#' 。

你可以认为输入格式总是有效的,例如它永远不会包含两个连续的逗号,比如 "1,,3" 。

示例 1:

输入: "9,3,4,#,#,1,#,#,2,#,6,#,#"
输出: true
示例 2:

输入: "1,#"
输出: false
示例 2:

输入: "1,#"
输出: false

一开始看到这题第一时间想到的是判断节点的入度出度,不过思路对了,但就是在奇妙的地方卡住了,永远剩下几个案例过不去,就很懵,然后看了下大佬的思路,学到了新姿势,用消除法去判断,就是当遇到“4,#,#”这种的,就将它转化为“#”,最后栈中只剩下一个“#”,那么这个树就是合理的,因为所有叶子节点都会有两个空节点,如果这是一颗合理的二叉树,那么我们将叶子节点变为空节点,之前的父节点最终也会变成叶子节点,直到最后,顶点也会变为一个空节点,思路新奇,然后就自己动手实现了一下。

class Solution {
public:
    bool isValidSerialization(string preorder) {
        int p_size = preorder.length();
        if (p_size == 0)return false;
        //关键点,是否遇到'#' 
        //遇到连续两个'#',代表这颗子树的末端
        vector<string> v;
        for (int i = 0; i < p_size;)
        {
            if (preorder[i] == ',') 
            { 
                i++; 
                continue;
            }
            if (preorder[i] != '#')
            {
                string tmp;
                while(i<p_size && preorder[i]!=','){
                    tmp+=preorder[i++];
                }
                v.push_back(tmp);
            }
            else
            {
                v.push_back("#");
                i++;
            }
            
            while(v.size()>2 && v.back() == "#" && *(v.rbegin()+1) == "#" && *(v.rbegin()+2) != "#")
            {
                v.pop_back();
                v.pop_back();
                v.pop_back();
                v.push_back("#");
            }
        }

        if(v.size() == 1 && v[0] == "#")return true;
        return false;
    }
};
原文地址:https://www.cnblogs.com/xiangqi/p/14523441.html