【力扣】(中等) 331. 验证二叉树的前序序列化 ---- 辅助栈

  • 331 验证二叉树的前序序列化
  • 来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/verify-preorder-serialization-of-a-binary-tree
  • 序列化二叉树的一种方法是使用前序遍历。当我们遇到一个非空节点时,我们可以记录下这个节点的值。如果它是一个空节点,我们可以使用一个标记值记录,例如 #。
     _9_
    /   \
   3     2
  / \   / \
 4   1  #  6
/ \ / \   / \
# # # #   # #

例如,上面的二叉树可以被序列化为字符串 “9,3,4,#,#,1,#,#,2,#,6,#,#”,其中 # 代表一个空节点。

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

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

你可以认为输入格式总是有效的,例如它永远不会包含两个连续的逗号,比如 “1,3” 。

示例 1:

输入: "9,3,4,#,#,1,#,#,2,#,6,#,#"
输出: true

解题思路:【python3】(1) 辅助栈: 遇到数值压入栈,遇到‘#’弹出栈顶元素(前提: 栈不为空),注意到最后一个一定是‘#’且其数量比数值数量多1,用num_nodes记录遍历节点的数量, 当遇到‘#’时,若栈为空且num_nodes + 1==preorder节点数即遍历至字符串的末尾,返回true,否则返回false。 (2)槽位: 只要存在一非数值节点,其必存在两个子节点,用槽位slots记录节点数,初始为 1,遍历preorder所有节点,每遍历一次slots减 1,若该节点为非空节点,slots加2,若slots<0,则返回false。最终如果slots=0返回true。

Notes 1 : 二叉树一个重要的性质是叶子节点的数量是非叶子节点数量之和+1.

Notes 2 : 刚开始遍历字符串的时候,用的for s in preorder,问题是若节点数值为多位数,则无法得到正确节点数。学到了--------preorder.split(',')-----------得到以逗号间隔的若干字符组成的list,例如([‘9’, ‘#’, ‘92’, ‘#’, ‘#’])。

【c++】辅助栈: 只是因为没有找到类似python里split这种好用的函数,就换了一种解决方式,基本思想一致。遍历preorder,遇到数值节点将0压入栈(压入随意什么数值),为了解决多位数的问题,在遇到‘,'或者下标超出范围之前,i++,跳过这些位到逗号后的下一个节点。遇到‘#’,若栈不为空弹出栈顶元素,为空判断是否遍历至字符串结尾,是返回true,否则false。

Notes 3 : while条件里要加 i 范围限制,不然就死循环了.

# python 3
class Solution:
    def isValidSerialization(self, preorder: str) -> bool:
        # solution 1:
        # stack = []
        # num_nodes = 0
        # print(preorder.split(','))
        # for s in preorder.split(','):
        #     if s == '#' :
        #         if stack: 
        #             stack.pop()
        #             num_nodes +=1
        #         else: 
        #             if num_nodes+1== len(preorder.split(',')): return True
        #             else: return False
        #     else: 
        #         stack.append(s)
        #         num_nodes +=1
        # return False

        # solution 2:
        stack = []
        if len(preorder.split(',')) == 0: return True
        slots = 1
        for node in preorder.split(','):
            slots -= 1
            if slots<0 : return False
            if node !='#' : slots += 2
        return slots==0
// c++
class Solution {
public:
    bool isValidSerialization(string preorder) {
        if (preorder.empty()) return true;
        stack<int> my_stack;
        for (int i =0 ; i< preorder.size(); ++i){
            if (preorder[i] == '#'){
                if(!my_stack.empty()) my_stack.pop();
                else if (i+1 == preorder.size()) return true;
                else return false;
            }
            else if(preorder[i]!=','){
                // while条件里要加 i 范围限制,不然就死循环了
                while(preorder[i]!=',' && i< preorder.size()) ++i;
                my_stack.push(0);
            }
        }
        return false;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值