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

29 阅读2分钟

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

解题思路

本题大意是判断给定的序列符不符合一个二叉树的前序遍历顺序,就是满足先根结点,在左子数,最后右子树的顺序,由于给的参数是一个字符串则在遍历时注意跳过无关字符(如‘,’以及多位数)

解题方法

· 建立一个字符动态数组用于存储遍历字符串得到的‘#’以及数字字符

· 特别注意如果遇到多位数字字符只需处理一次可只处理首位数字字符其余以及‘,’都跳过

· 因为叶子结点无左右子树,所以当遍历到当前字符为‘#’且动态数组最后也为‘#’进行两次删除末尾元素并继续进行循环判断

· 注意如果连续遍历到3个‘#’则该序列已经非法返回false

· 每次正常遍历都将遍历到的字符进行插入动态数组末尾操作 (若已经找到叶子结点说明该叶子结点所在的子树已经寻找完毕则只需将一个空结点入队列方便下一次判断

· 遍历完成如果动态数组此时长度为1并且元素为‘#’则该前序遍历合法返回true否则返回false

代码实现
class Solution {
public:
    <!-- int fast_io=[](){
        ios::sync_with_stdio(false);
        cin.tie(0);
        cout.tie(0);
        return 0;
    }(); 
    骗骗用时()-->
    bool isValidSerialization(string preorder) {
        vector<char> str;
        int sum=0;
        for(int i=0;i<preorder.size();++i){
            if(preorder[i]==','|| i>0&&preorder[i-1]>='0'&&preorder[i-1]<='9'&&preorder[i]>='0'&&preorder[i]<='9')
                continue;
            if(preorder[i]=='#'){
                sum++;
                if(sum>2)
                    return false;
            }
            else
                sum=0;
            while(preorder[i]=='#'&&str.size()>=2&&str.back()=='#'){
                str.pop_back();
                str.pop_back();
                sum=1;
            }
            str.push_back(preorder[i]);
        }
        if(str.size()==1&&str[0]=='#')
            return true;
        return false;
    }
};

(这是菜菜本人在掘金的第一篇,打卡记录一下(∠・ω< )⌒★)

补上题目:

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

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

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

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

你可以认为输入格式总是有效的

  • 例如它永远不会包含两个连续的逗号,比如 "1,,3" 。

注意: 不允许重建树。

示例 1:

输入: preorder = "9,3,4,#,#,1,#,#,2,#,6,#,#"
输出: true

示例 2:

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

示例 3:

输入: preorder = "9,#,#,1"
输出: false

提示:

  • 1 <= preorder.length <= 104
  • preorder 由以逗号 “,” 分隔的 [0,100] 范围内的整数和 “#” 组成