Leetcode 1028. 从先序遍历还原二叉树

这篇博客介绍了如何根据LeetCode 1028题目的先序遍历结果,重建二叉树。题目要求从深度优先搜索的输出序列恢复原始二叉树结构,并给出了不同示例的输入输出。博主将详细解释解题思路和算法实现。
摘要由CSDN通过智能技术生成
1,题目:

我们从二叉树的根节点 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]

  • 提示:
    原始树中的节点数介于 1 和 1000 之间。
    每个节点的值介于 1 和 10 ^ 9 之间。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/recover-a-tree-from-preorder-traversal
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

2,算法说明:
1) 切割字符串,通过判断'-'的个数来算出第几层;通过strconv.Atoi来转换字符串到数字
2) 递归左右两边二叉树
3) 直接看代码,代码每一步都解释了,先看getDepth()函数,再看m()函数,
最后看recoverFromPreorder()函数
4) 觉得有启发的话,希望给个赞
3,代码
* Definition for a binary tree node.
* type TreeNode struct {
*     Val int
*     Left *TreeNode
*     Right *TreeNode
* }
*/
//主体函数
func recoverFromPreorder(S string) *TreeNode {
   //如果字符串为空,则返回nil
   if len(S) == 0 {
       return nil
   }
   //调用迭代的函数,迭代大法好,二叉树的问题用迭代能解决一大半
   //默认父亲层数是-1
   _ , node := m(S , -1)
   return node
}

//迭代函数,需要传入字符串,父亲层数
func m(S string , parent_depth int) (string , *TreeNode){
   //如果字符串为空,就返回nil,也不用进行迭代了
   if len(S) == 0 {
       return S , nil
   }
   //通过截取字符串来解析当前是第几层,数值,剩余的字符串
   d , n , St := getDepth(S)
   //如果层数小于 && 等于 父亲层数,说明不要继续迭代了,需要返回
   //这一步我认为是核心判断条件,关键靠这一步才能还原正确
   if d <= parent_depth{
       return S , nil
   }
   //根据数值new出一个二叉树
   node := &TreeNode{Val:n}
   //递归,得到二叉树左边,以及剩余的字符串
   St , node.Left = m(St , d)  
   //递归,得到二叉树右边,以及剩余的字符串
   St , node.Right = m(St , d)
   return St , node
}

//通过截取字符串来解析当前是第几层,数值,剩余的字符串
func getDepth(S string) (int , int, string){
   depth := 0
   //通过判断'-'的个数,来算出第几层
   for i := 0 ; i < len(S) ; i++{
       if S[i] == '-'{
           depth += 1
       }else{
           break
       }
   }
   //转换字符串到数字,默认是截取到字符串最后一位,
   //这样是为了避免传进来的字符串就没有包含'-'
   endIdx := len(S)
   for i := depth ; i < len(S) ; i++{
       if S[i] == '-'{
           endIdx = i
           break
       }  
   }
   //基本不用考虑是否会转换出错
   str , _ := strconv.Atoi(S[depth:endIdx]) 
   //返回 第几层,数值,剩余的字符串
   return depth , str , S[endIdx:len(S)]
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值