LeetCode 331. Verify Preorder Serialization of a Binary Treet 二叉树前序遍历验证 Python Solution

来源:互联网 发布:mysql大神博客 编辑:程序博客网 时间:2024/06/07 06:28

此题目对应于LeetCode 331

题目要求一个前序遍历字符串是否能对应一个二叉树,值得注意的是原二叉树的空节点都用#代替了。

解这个题目需要先介绍一些预备知识:

1.二叉树中节点的度数指的是该几点底下有多少个孩子节点,如下图中针对结点1,他下面有两个孩子3、4,所以说结点1的度为2;针对结点4,他下面一个孩子都没有,所以说结点4的度为0.



2.二叉树中节点数和度数的关系式。


二叉树总节点数目为N,N=N0+N1+N2,其中Ni表示度数为i的节点的数目;

二叉树度数总和为M=0*N0+1*N1+2*N2


又有二叉树的节点数比总度数多1的性质(可以理解成结点自己的头上有一根“绳子”挂着自己),

则有M=N+1,N1+2*N2=N0+N1+N2即为N0=N2+1


对于题目中的二叉树,由于用#代替了空叶子节点,所以并没有任何度数为1的节点,同时可以将

#代替了空叶子节点形成的二叉树看成一个新的二叉树。设二叉树总节点数目为NN0

#代替了空叶子节点的数目,则可以发现这样的二叉树的前序遍历中存在如下规律:

1)以#结束

2N=2N0-1

3)同时可以发现,以#为结束的子序列中,如果中途某个地方,已经满足(1)(2)条件,即

前面序列已经构成一个完整的数了,则后面的序列多余,也就是该序列无法构成合法的二叉树。

ps:如果只使用(1)(2)限制会发现有部分测试案例是情况(3)无法通过。

下面附上Python代码


# -*- coding: utf-8 -*-class Solution(object):    def isValidSerialization(self, preorder):        st = list(preorder.split(','))        if len(st)==1 and st[0]=='#':#边界条件            return True        idx = [i for i,x in enumerate(st) if x == '#']#‘#’的下标list        tag = False        for i in idx:            N = len(st[:i+1])            N0 = st[:i+1].count('#')            if N == 2*N0-1 and st[-1]=='#':# i+1==len(st)                tag = True            if tag:#判断中途是否满足前面序列构成树的条件                if i+1==len(st):#最后满足                    return True                else:#中途满足                    return False        return False        """        :type preorder: str        :rtype: bool        """        
这个算法的时间复杂度明显是O(n),但是运行时间却是比较久600ms左右,我暂时也没找到好的解法,如果谁有更好的解法可以

留言。







阅读全文
0 0