[路飞]_程序员必刷力扣题: 331. 验证二叉树的前序序列化

194 阅读3分钟

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

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

示例 3:

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

栈的思想

思路

我们知道树状数据结构会有左节点和有节点,我们用stack来保存树中的每个节点需要被填补的空节点数量

  • 处理根节点,根节点为空时,此时只需要填补根节点一个空位,因此stack中默认有一个1,1代表此时拥有一个空节点

这里我们通过split,将字符串转成数组,得到所有节点的数组nodeArr,然后遍历处理没一个节点

  • 如果节点为#,则代表有一个空节点被#代替,且不产生新的空节点,所以直接将stack中末尾的空节点数量-1,此时要判断,如果stack最后一个值为0,则代表该节点的空白都被填满,所以需要弹出

  • 如果节点为数字,则代表有一个空节点被数字代替,且产生两个新节点,所以要先判断代替一个空节点后,stack末尾的空节点数量-1后是否为0,为0则弹出,不为0则不用处理,然后向stack中push一个2,2代表该数字节点产生的两个新的空节点

判断条件

  • 如果是一个完整的树,最后应该没有空节点,所以只需要判断stack的length是否为0即可
var isValidSerialization = function (preorder) {
    var nodeArr = preorder.split(',')
    var stack = [1]
    for (var i = 0; i < nodeArr.length; i++) {
        if(stack.length===0) return false
        var item = nodeArr[i]
        
        stack[stack.length-1]--
        if(stack[stack.length-1]===0){
            stack.pop()
        }
        
        if (item !== '#') {
            stack.push(2)
        }
    }
    return stack.length===0
};

计数

思路

这里思想同上,只不过需要填补的节点我们用slot来记录

  • 根节点未放置的时候,slot为1,表示需要放入一个节点来填补
  • 每填补一个数字,则会占用一个节点,slot--,但是会新增两个空节点,slot+=2
  • 每遇到一个#,则填补一个null到一个空节点,slot--

判断条件

  • 最后只需要判断是否所有的节点都被填补,即slot===0
var isValidSerialization = function (preorder) {
    var nodeArr = preorder.split(',')
    var slot = 1
    for (var i = 0; i < nodeArr.length; i++) {
        if(slot===0) return false
        var item = nodeArr[i]
        switch(item){
            case '#':
                slot--
                break;
            default:
                slot++
                break;
        }
    }
    return slot===0
};