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

题目:

思路:

这道题是我今天目前碰到最有意思的题,首先思考只有前序遍历是无法完全确立重建二叉树的

在无法确立二叉树的情况下,得想想二叉树的其他性质

利用性质:空节点视为叶节点,根据性质叶节点数目比非叶节点数目多1来判断。

我们可以定义一个概念,叫做槽位,二叉树中任意一个节点或者空孩子节点都要占据一个槽位。二叉树的建立也伴随着槽位数量的变化。开始时只有一个槽位,如果根节点是空节点,就只消耗掉一个槽位,如果根节点不是空节点,除了消耗一个槽位,还要为孩子节点增加两个新的槽位。之后的节点也是同理。

有了上面的讨论,方法就很简单了。依次遍历前序序列化,根据节点是否为空,按照规则消耗/增加槽位。如果最后可以将所有的槽位消耗完,那么这个前序序列化就是合法的。

  • 开始时只有一个可用槽位。

  • 空节点和非空节点都消耗一个槽位。

  • 空节点不增加槽位,非空节点增加两个槽位。

算法实现:

  • 初始化可用槽位为 1:slots = 1。
  • 遍历前序序列化字符串,每遍历到逗号字符:
    •     空节点和非空节点都消耗一个槽位:slots = slot - 1。
    •     如果当前可用槽位是负数,那么这个先序序列就是非法的,返回 False。
    •     非空节点(即逗号字符前不是 #),新增两个可用槽位:slots = slots + 2`。
  • 最后一个节点需要单独处理,因为最后一个节点后面是没有逗号的。
  • 如果可用槽位全部被消耗完,那么该前序序列化就是合法的:返回 slots == 0。

代码:

class Solution {
public:
    bool isValidSerialization(string preorder) {
    /*基本思想:根据先序二叉树和中序/后序的不同 先序遍历先访问根节点 中序和后续先访问叶节点*/
        int degree = 1;//根节点出度-入度 为2 比正常节点出度-入度 多1
        for(int i=0;i<preorder.size();i++){
            if(degree==0)
                return false;
            if(preorder[i]==',')
                continue;
            if(preorder[i]=='#')//遇到叶节点度数减一
                degree-=1;
            else{
                while(i<preorder.size()&&preorder[i]!=',')//处理节点编号为多位数字的情况
                    i++;
                degree+=1;
            }
        }
        return degree==0;
    }
};
发布了377 篇原创文章 · 获赞 344 · 访问量 17万+

猜你喜欢

转载自blog.csdn.net/qq_41895747/article/details/105215609