每日一题 LeetCode331. 验证二叉树的前序序列化 java题解

***我怎么一题都不会md

题目

https://leetcode-cn.com/problems/verify-preorder-serialization-of-a-binary-tree/
在这里插入图片描述

方法一

分析

我们可以定义一个概念,叫做槽位。一个槽位可以被看作「当前二叉树中正在等待被节点填充」的那些位置。
二叉树的建立也伴随着槽位数量的变化。每当遇到一个节点时:
如果遇到了空节点,则要消耗一个槽位;
如果遇到了非空节点,则除了消耗一个槽位外,还要再补充两个槽位。

我们使用栈来维护槽位的变化。栈中的每个元素,代表了对应节点处剩余槽位的数量,而栈顶元素就对应着下一步可用的槽位数量。当遇到空节点时,仅将栈顶元素减 1;当遇到非空节点时,将栈顶元素减 1 后,再向栈中压入一个 2。无论何时,如果栈顶元素变为 0,就立刻将栈顶弹出。

遍历结束后,若栈为空,说明没有待填充的槽位,因此是一个合法序列;否则若栈不为空,则序列不合法。此外,在遍历的过程中,若槽位数量不足,则序列不合法。

代码

class Solution {
    public boolean isValidSerialization(String preorder) {
        Deque<Integer> stack=new LinkedList<>();
        stack.push(1);
        int i=0;
        int n=preorder.length();
        while(i<n){
            if(stack.isEmpty()){
                return false;
            }
            if(preorder.charAt(i)==','){
                i++;
                continue;
            }
            else if(preorder.charAt(i)=='#'){
                i++;
                int top=stack.pop()-1;
                if(top>0){
                    stack.push(top);
                }
            }
            else if(Character.isDigit(preorder.charAt(i))){
                while(i<n&&Character.isDigit(preorder.charAt(i))){
                    i++;
                }
                int top=stack.pop()-1;
                if(top>0){
                    stack.push(top);
                }
                stack.push(2);
            }
        }
        return stack.isEmpty();
    }
}

复杂度

时间复杂度:O(n),其中 n 为字符串的长度。我们每个字符只遍历一次,同时每个字符对应的操作都是常数时间的。
空间复杂度:O(n)。此为栈所需要使用的空间。

空间优化代码

class Solution {
    public boolean isValidSerialization(String preorder) {
        int slot=1;
        int i=0;
        int n=preorder.length();
        while(i<n){
            if(slot==0){
                return false;
            }
            if(preorder.charAt(i)==','){
                i++;
                continue;
            }
            else if(preorder.charAt(i)=='#'){
                i++;
                slot=slot-1;
                
            }
            else if(Character.isDigit(preorder.charAt(i))){
                while(i<n&&Character.isDigit(preorder.charAt(i))){
                    i++;
                }
                slot=slot-1+2;
            }
        }
        return slot==0;
    }
}

空间优化复杂度

时间复杂度:O(n),其中 n 为字符串的长度。我们每个字符只遍历一次,同时每个字符对应的操作都是常数时间的。
空间复杂度:O(1)。

方法二

在这里插入图片描述

方法三:前序序列建树

class Solution {
    int i;
    public boolean isValidSerialization(String preorder) {
        String[] strings = preorder.split(",");
        i = 0;
        //构建完整棵树以后,序列化中的所有结点都应被用到,也就是 i == strings.length
        return canBuild(strings) && i == strings.length;
    }

    public boolean canBuild(String[] strings) {
        //如果在建立当前结点时发现序列化中没有结点了,那就返回 false
        if (i == strings.length) {
            return false;
        }
        //如果当前结点是 null,就返回 true
        if (strings[i++].equals("#")) {
            return true;
        }
        //构建左子树和右子树
        return canBuild(strings) && canBuild(strings);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值