leetcode1028. 从先序遍历还原二叉树(Python3)

leetcode1028. 从先序遍历还原二叉树

我们从二叉树的根节点 root 开始进行深度优先搜索。

在遍历中的每个节点处,我们输出 D 条短划线(其中 D 是该节点的深度),然后输出该节点的值。(如果节点的深度为 D,则其直接子节点的深度为 D + 1。根节点的深度为 0)。

如果节点只有一个子节点,那么保证该子节点为左子节点。

给出遍历输出 S,还原树并返回其根节点 root

示例 1:

输入:"1-2--3--4-5--6--7"
输出:[1,2,5,3,4,6,7]

示例 2:

输入:"1-2--3---4-5--6---7"
输出:[1,2,5,3,null,6,null,4,null,7]

示例 3:

输入:"1-401--349---90--88"
输出:[1,401,null,349,88,90]

提示:

  • 原始树中的节点数介于 11000 之间。
  • 每个节点的值介于 110 ^ 9 之间。

方法:哈希表

思路:

我们首先考虑先序遍历的特点,先根节点→左子树→右子树。这样的顺序也就意味着,同一层的结点,一定是最左边的先遍历到,最右边的后遍历到;且遍历到同一层的第二个结点时,这一层第一个结点的左右子树已经遍历完了,第一个结点就不需要再更改了,因此我们每次,每一层只需要保留一个该层的结点即可。

我们使用哈希表tree_dic来保存每一层当前遍历到的结点,键为深度,值为树结点,根节点的键为0。然后开始遍历字符串S,根据’-'的数量计算这个节点的深度depth,获得这个结点的值value。因为子节点比父节点的深度大1,且题目说,如果节点只有一个子节点,那么保证该子节点为左子节点,只要判断此时depth-1层的结点tree_dic[depth-1]的左结点是否存在,存在的话,把当前的节点连接到它的右子节点上,不存在的话连接到左子节点上;然后将tree_dic[depth]更新为当前节点即可

最后返回tree_dic[0],即根节点,如果根节点不存在,返回None。

代码:

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def recoverFromPreorder(self, S: str) -> TreeNode:
        #初始化字典,键为层数,值为该层目前遍历到的最后一个结点
        tree_dic = dict()
        i = 0
        while i < len(S):
            depth = 0
            value = ''
            while i < len(S) and S[i] == '-':
                depth += 1
                i += 1
            while i < len(S) and S[i].isdigit():
                value += S[i]
                i += 1
            #此时depth为这个节点的深度,value为这个节点的值(str形式)
            #生成节点
            node = TreeNode(int(value))
            if depth > 0:
                #判断此时,比它深度少1的结点有没有左结点,没有就连上,有就作为右结点
                if tree_dic[depth-1].left:
                    tree_dic[depth-1].right = node
                else:
                    tree_dic[depth-1].left = node
            #更新这个深度的最后一个节点为node
            tree_dic[depth] = node
            #最后返回根节点
        return tree_dic[0] if tree_dic[0] else None

结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值