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

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

例如,上面的二叉树可以被序列化为字符串 "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
/**
 * @param {string} preorder
 * @return {boolean}
 */
var isValidSerialization = function(preorder) {
    let n = preorder.length;
    let i = 0;
    let stack = [1];
    while(i < n){
        if(!stack.length) return false;
        if(preorder[i] == ","){
            i++;
        } else if(preorder[i] == "#"){
            stack[stack.length - 1]--;
            if(stack[stack.length - 1] == 0){
                stack.pop();
            }
            i++;
        } else {
            while(i < n && preorder[i] !== ","){
                i++;
            }
            stack[stack.length - 1]--;
            if(stack[stack.length - 1] == 0){
                stack.pop();
            }
            // 不同的是,我们找到的是数字,只要是有效数字必然会有两个儿子节点,还需要我们继续往后找
            stack.push(2);
        } 
    }
    return !stack.length;
};

// 画图来讲下这个图 比较形象

// 根据例子一来看,首先我们有个栈,

// 首先,栈里面得有个1,代表即将要添加一个元素进来,然后就拿到这个9,代表拿到一个真正的节点,现在不需要这个1了,给他-1

// 变成0;但是压入栈的数字变成0,代表我们把想要的节点压入进来了,现在开始弹栈了

// 但是一个节点下面有两个儿子节点,所以说我们再给他添加两个节点进来,所以给他压入一个2;压入2 代表我们需要添加两个节点,不管这两个节点是否为空;

// 接下来,我们拿到了一个节点3,拿到了一个,就把 2-1;此时还有一个节点未添加;此时3也是个有效节点,有效节点证明3下面也有两个儿子;

// 所以再压入一个2;接着往下找,找到了一个4,证明 3已经找到了一个儿子节点,就把这个2-1;这个时候4也是一个有效节点,所以再压入一个2,证明我们下面还需要加两个子节点;

// 然后是两个#号,#号代表是空节点,空节点下面是没有儿子的;所以说。我们就只添加不消耗;就把栈顶的2给消耗了

// 然后把这两个#号销掉了,往后找到了一个1,那么这个1 是3的另一个儿子,此时3的两个儿子都已经找打了,所以就把此时栈顶的1,给消耗了。

// 但是这个3 被消耗掉了,这个1也是有效数字,1下面还有两个儿子,再把2给压入栈,发现1 后面是有两个#,

// #代表只消耗不增加,所以把栈顶的2 给消耗了;

// 后面发现了数字2,从数字3到 2 前面的位置,这一段已经找完了,发现数字是数字9的儿子,所以数字9的位置就是0了

//  -1 +2;

// 所以9的儿子 3和2已经找完了;发现2也是有效数字,下面也有两个儿子,往后找,发现一个#,#号是只消耗不增加,

// 所以栈顶2减去1,所以往后找,发现,2有两个儿子,一个是#号,一个是6,所以栈顶的1被新找到的儿子6给消耗掉了;6下面也有两个儿子 ;压入2,往后找是两个#号,继续消耗,变成了0; 此时栈已经空了,证明这个序列化就是正确的;




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值