[路飞]_LeetCode331. 验证二叉树的前序序列化

170 阅读2分钟

「这是我参与11月更文挑战的第14天,活动详情查看:2021最后一次更文挑战

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

题目要求

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

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

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

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

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

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

示例

输入: "9,3,4,#,#,1,#,#,2,#,6,#,#"
输出: tru

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

思路

解释:我们可以把#想象成null,null的下面将不在生成节点,每一个父节点的下面都会有两个子节点,遍历到最后都是null的情况下如果数组里面还有没遍历完的值说明不符合条件,否则就是符合条件。

一个正常的节点就对应两个位置,我们维护一个count = 1的变量,如果第一个遍历的值是正常数字就把count-1,然后再给count = 2,如果遇到一个#我们就把count-1,直到最后遍历完或者count == 0了就停止遍历返回不符合条件。

代码

var isValidSerialization = function(preorder) {    
    let len = preorder.length;    
    let num = 0;    
    let count = 1;    
    while (num < len) {        
        if (!count) return false;        
        if (preorder[num] === ',') {            
            num++;        
        } else if (preorder[num] === '#') {            
            count--;            
            num++;        
        } else {            
            while (num < len && preorder[num] !== ',') {                
                num++;            
            }            
            count++;            
            num++;        
        }    
    }    
    return !count
};