331. 验证二叉树的前序序列化 - leetcode刷题(C++)

一、题目

331. 验证二叉树的前序序列化
这个题我写的有些复杂,但是很好理解。

二、分析

  1. 首先注意到,题目中非叶子节点,都有两个子节点,#或者数字,所以可以将两个连续的##和一个数字相抵消成一个#
    在这里插入图片描述
    如果是一个正确的二叉树的前序序列化,那么这样消除,最后只剩下一个根节点:#
    我用的栈进行操作。
  2. 要注意一些特殊情况:比如"9,#,92,#,#"
    我的做法首先将每个节点都暂存到vector中,当然也可以用split函数按逗号分隔。
9 3 4 # # 1 # # 2 # 6 # #
----- 入栈过程 ------
9 入栈, 3入栈, 4入栈, # 入栈
#,由于栈顶是#,将其出栈,可以和 4合并成一个#。
1 入栈, #入栈
#,由于栈顶是#,将其出栈,可以和1合并成一个#(a),但是合成之后,发现栈顶还是#(b),还要出栈,#(a)与#(b)与3,再次合成#。
...
最后栈中剩余一个#。
----- 栈元素变化 -----
9
9 3
9 3 4
9 3 4 # // 4## -> #
9 3 #
9 3 # 1
9 3 # 1 #   // 1## -> #    3## -> #
9 # 
9 # 2
9 # 2 #
9 # 2 # 6
9 # 2 # 6 #  // 6## -> #   2## -> #  9## -> #
#

三、代码

class Solution {
public:
    bool isValidSerialization(string preorder) {
        stack<string> s1;
        int n(preorder.length());
        if(n <= 1){
            if(n == 1 && preorder[0] == '#') return true;
            return false;
        }
        // 将字符串中的节点值取出来
        vector<string> vec;
        string temp = "";
        for (int i = 0; i < n; i++)
        {
            if (preorder[i] == ',')
            {
                vec.push_back(temp);
                temp = "";
                continue;
            }
            if (i == n - 1)
            {
                temp += preorder[i];
                vec.push_back(temp);
                break;
            }
            temp += preorder[i];
        }
        n = vec.size();
        //开始入栈检查前序
        for(int i = 0; i < n; i++){
            if(vec[i] != "#"){
                s1.push(vec[i]);
            }else{
            	//遇到#时,如果栈顶不是#,直接入栈
                if(s1.empty() || s1.top() != "#"){
                    s1.push("#");
                }else{
                //如果栈顶是#,则需要每次出栈一个 # 和一个 not# 
                //直到栈顶不是 # 或者空,也就是从叶子节点找到了暂时的 not# 父节点
                    while(!s1.empty() && s1.top() == "#"){
                        s1.pop(); // #
                        // 如果出栈的过程中直接空了,返回错误
                        if(s1.empty()) return false;
                        s1.pop(); // not #
                    }
                    s1.push("#");
                }
            }
        }
        //最后判断栈中元素唯一,且为 #
        if(!s1.empty()){
            s1.pop();
            if(s1.empty()) return true;
        }
        return false;
    }
};
···
执行用时:4 ms, 在所有 C++ 提交中击败了74.27%的用户
内存消耗:10.8 MB, 在所有 C++ 提交中击败了5.07%的用户

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值