[路飞]_一起刷leetcode 331. 验证二叉树的前序序列化

「这是我参与11月更文挑战的第8天,活动详情查看: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
复制代码

思路

  1. 先找规律, 每个节点可以有两个子节点, 但是除了根节点之外,其他的节点每次必须占用一个空位,相当于只增加一个空位;
  2. 定义变量prev用来记录我们可以插入的空位,我们只需要统计循环结束后空位是否刚好为0即可;根节点加两个空位,普通节点加一个空位,"#"节点减一个空位;
  3. 找边界, 一开始得判断根节点是不是空节点,如果是空节点,判断后面是否有剩余元素;
  4. 如果空位为0, 说明不能插入元素了,这时候后面不能有元素;

实现

function isValidSerialization(preorder) {
    let arr = preorder.split(",");
    // 只有空的根节点能以"#"开头
    if (arr[0] === "#") {
        return arr.length === 1;
    }

    // 根节点已经判断过非空了, 有两个空位
    let prev = 2;
    const n = arr.length;

    for (let i = 1; i < n; i++) {
        if (arr[i] === "#") {
            prev--;
            // 如果没空位了,后面就不能有元素插入了
            if (prev === 0) {
                return i === n - 1;
            }
        } else {
            prev++;
        }
    }

    return prev === 0;
};
复制代码

看懂了的小伙伴可以点个关注、咱们下道题目见。如无意外以后文章都会以这种形式,有好的建议欢迎评论区留言。

猜你喜欢

转载自juejin.im/post/7033784669107650568