[LeetCode] 331. 验证二叉树的前序序列化

这篇博客主要介绍了如何通过前序遍历的方法,验证给定的数组序列是否能正确还原为二叉树。作者在过程中复习了二叉树的前序遍历,并通过创建树节点、准备数据源、实现前序遍历构建二叉树的过程,最终解决了LeetCode的331题。在解题中,作者注意到节点数量和null的数量关系,并据此修改了算法,成功通过所有测试用例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我就想练练前序遍历二叉树

Date Created: Mar 12, 2021 10:58 AM
Status: 要学习的

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

通过阅读题目发现最近对二叉树的联系比较少,所以准备用最直接的方法来做。

这面就想通过将数组还原成二叉树的方法,来判断数组是否是正确的。

起初是想就看数组能不能正确的通过前序方法来还原出来二叉树。就可以直接判断了。(后来才清楚并不是这面简单)

下一步就开始准备还原二叉树的材料了。

构建树节点

class Tree{
        String value;//这块用string 就是想通过string的.split(“,”) 直接使用了
        Tree left;
        Tree right;

        public Tree() {
        }

        public Tree(String value) {
            this.value = value;
        }
}

下一步…忘记了

复习下二叉树的前序遍历模板

// 简单的理解下 就是先打印根,再打印左节点,接下来是右节点。那么复制或者是重建也是这个顺序
public void preOrderTraverse1(TreeNode root) {
        if (root != null) {
            System.out.print(root.val + "->");
            preOrderTraverse1(root.left);
            preOrderTraverse1(root.right);
        }
}

那么下一步需要准备的是一个数据源(这里准备用一个可变长度的,用一个就少一个的数据结构,懒着记具体坐标了哈 我这面准备使用java的LinkedList().);

数据源准备

String[] split = preorder.split(",");
Deque<String> deque = new LinkedList<>();
for (String s : split) {
     deque.offer(s);
}

这一步也做完了下一步就是修改 将遍历的改成 创建二叉树;

通过前序的方式创建二叉树

// 入参本来想只用一个Deque了 但是咱要用递归嘛 所以就加上了一个Tree
private Tree getTree(Deque<String> strings,Tree tree){
        if (!strings.isEmpty()){ //递归终止条件
            if ("#".equals(strings.peek())) { //判断是不是一个岔到头了
                strings.pop(); //记得要把“#” 删除哈 第一次忘记删除了,就返回了一个岔
                return tree;
            }
            tree = new Tree(strings.pop()); //赋值根节点
            tree.left = getTree(strings, tree.left); //赋值左节点
            tree.right = getTree(strings, tree.right); //赋值右节点
        }
        return tree;
    }

好了 其实到这步对前序 复习的就差不多了,

下面开始解题哈哈

题目分析

是否能通过前序方式创建二叉树?

问题是咱们都创建好了,咋知道咱们创建的和数组提供的是一个呢?

比如 数组提供了 包含 6个节点的二叉树。 咱们通过它创建了 4个节点的。就说明他提供的是有问题的。我是这样想的。

所以就添加了变量来记录节点数量。要不然还要遍历就麻烦了。

private static Tree getTree(Deque<String> strings,Tree tree){
        if (!strings.isEmpty()){
            if ("#".equals(strings.peek())) {
                strings.pop();
                return tree;
            }
            num++; //这里添加了一个全局变量来记录-》节点数
            tree = new Tree(strings.pop());
            tree.left = getTree(strings, tree.left);
            tree.right = getTree(strings, tree.right);
        }
        return tree;
    }

之后在修改一下主方法

主方法

public Boolean isValidSerialization(String preorder) {
        String[] split = preorder.split(",");
        Deque<String> deque = new LinkedList<>();
        int nodeNum = 0;
        for (String s : split) {
            deque.offer(s);
            if (!"#".equals(s)) {
                nodeNum++;
            }
        }
        getTree(deque, null);//这里都没用上创建好的二叉树,重点是练习下哈 所以用不用上无所谓 哈哈
        return nodeNum == num ;
    }

自信满满提交了,显然存在问题

被测试用例打脸了 【1,#】

想了想发现,节点数对了 但是 null 的数量不对。

一个节点 对应两个null

两个节点 对应三个null

三个节点 对应四个null

修改后的主方法

public static Boolean isValidSerialization(String preorder) {
        String[] split = preorder.split(",");
        Deque<String> deque = new LinkedList<>();
        int len = split.length;
        int nodeNum = 0;
        int nullNum = 0; //记录下null节点的数量
        for (String s : split) {
            deque.offer(s);
            if (!"#".equals(s)) {
                nodeNum++;
            }
        }
        nullNum  = len - nodeNum;
        getTree(deque, null);

        return (nodeNum == num)&&(nullNum == nodeNum+1) ; //添加判断
    }

过啦

复习就到这里啦。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值