栈---验证二叉树的前序序列

本文介绍了一种算法,用于验证给定字符串是否为正确二叉树的前序序列化。通过使用栈来跟踪节点的孩子标识,确保每个节点的左右孩子都有对应的标识,要么为数字要么为#。该算法在不重建树的情况下完成验证。

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

  1. 题目
    序列化二叉树的一种方法是使用前序遍历。当我们遇到一个非空节点时,我们可以记录下这个节点的值。如果它是一个空节点,我们可以使用一个标记值记录,例如 #。
    _9_
    /   \
   3     2
  / \   / \
 4   1  #  6
/ \ / \   / \
# # # #   # #
例如,上面的二叉树可以被序列化为字符串 "9,3,4,#,#,1,#,#,2,#,6,#,#",其中 # 代表一个空节点。

给定一串以逗号分隔的序列,验证它是否是正确的二叉树的前序序列化。编写一个在不重构树的条件下的可行算法。

每个以逗号分隔的字符或为一个整数或为一个表示 null 指针的 '#' 。

你可以认为输入格式总是有效的,例如它永远不会包含两个连续的逗号,比如 "1,,3" 。
  1. 示例
输入: "9,3,4,#,#,1,#,#,2,#,6,#,#"
输出: true
输入: "1,#"
输出: false
输入: "9,#,#,1"
输出: false

3.代码实现
思路:正确序列化要求每个数字节点的左,右孩子都会有相应标识,要么为“#”要么为数字。
a.若为数字,则入栈,取序列下一个元素,下一个元素应为栈顶元素的左孩子,成功取到,置当前元素为栈顶元素的左孩子,继续上述步骤,直到为“#”结束;(若不能取到下一个元素,表示当前节点左孩子无标识)
b.栈顶元素左孩子“#”,则下一个元素应为栈顶元素的右孩子,假定栈顶元素右孩子会有标识(即可以成功取到序列当中下一个元素),弹出栈顶元素,置当前元素为栈顶右孩子;继续a步骤。(不能取到序列当中的元素,表示栈顶元素右孩子无标识)
c.上述a,b操作无任何异常出现,且栈为空,序列刚好到末尾可认定为正确的序列化。

public class Solution {
    //正确序列化要求每个数字节点的左,右孩子都会有相应标识,要么为“#”要么为数字。
    public boolean isValidSerialization(String preorder) {
        int i = 0;
        Stack<String> stack = new Stack<>();
        String[] nums = preorder.split(",");
        String c = nums[i];
        while (!c.equals("#")||!stack.empty()){
            while (!c.equals("#")){
                stack.push(c);
                //取下一个序列
                if(i<nums.length-1){
                    i++;
                    c = nums[i];
                }else{
                    //表示当前节点左孩子无标识
                    return false;
                }
            }
            if (!stack.empty()){
                //弹出栈顶元素,先假定其右孩子有相应标识
                stack.pop();
                //假定成立
                if(i<nums.length-1){
                    i++;
                    c = nums[i];
                }else{
                    //假定不成立
                    return false;
                }
            }
        }
        return stack.empty()&&i==nums.length-1;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值