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

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

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

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

 

题解:

1.字符串还原二叉树

2.输入中数字前的划线D 条短划线表示节点深度为D

3.根节点的深度为 0

4.节点只有一个子节点,该子节点为左子节点

 

示例 1

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

输入:"1-2--3--4-5--6--7"

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

示例 2:

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

输入:"1-2--3---4-5--6---7"

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

示例 3:

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

输入:"1-401--349---90--88"

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

提示:

原始树中的节点数介于 1 和 1000 之间。

每个节点的值介于 1 和 10 ^ 9 之间

 

解题思路:

  • 由于规定是先序遍历还原二叉树,先序遍历先根节点,不断遍历左子节点,再遍历右子节点

  • 分开几记录节点深度和节点值,节点值通过字符数字转换过去

  • 使用一个临时容器存放生成的节点

  • 如果节点深度小于容器中建成的树节点,则把工作指针回退到节点深度层上,对容器不断pop,回退到对应层,此时工作指针在容器最后一个节点上

  • 扩展子节点,先扩展左子节点(保证节点只有一个子节点,该子节点为左子节点),如果存在左子节点再扩展右子节点

C/C++题解:

/** * Definition for a binary tree node.

 * struct TreeNode {

 *     int val;

 *     TreeNode *left;

 *     TreeNode *right;

 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}* }; */

class Solution {

public:

    TreeNode* recoverFromPreorder(string S) {

        vector<TreeNode*> buffer;

        int idx=0; //遍历指针

        int slen=S.length();

        TreeNode* head=new TreeNode(0);

        TreeNode* nd=head;

        while(idx<slen){

            int lev=0;

            int val=0;

            while(idx<slen && S[idx]=='-'){

                ++lev;//数字前‘-’个数表示节点树深度

                ++idx;//跳过‘-’字符

            }//根据输入,如果是数字字符,则是节点值;连续数字字符是一个数

            while(idx<slen && S[idx]>='0' && S[idx]<='9'){

                val*=10; //计算出连续数字字符表示的数值

                val+=S[idx]-'0';

                ++idx;

            }//如果输入的树深比当前记录的节点数少,退回到树深为lev时的节点

            while(lev<buffer.size())buffer.pop_back();

            if(!buffer.empty())nd=buffer.back();//指针回到lev层

            if(nd->left==nullptr){//左节点为空

                nd->left=new TreeNode(val);//为其生成左子节点

                nd=nd->left; }//并走到左子节点位置

            else {//左子不空,有节点,生成右子节点

                nd->right=new TreeNode(val);

                nd=nd->right;//走到右子节点位置

            }//buffer容器存放建立过的树节点

            buffer.push_back(nd); }

        return head->left; }};//树从head-left开始,head头指针

Debug结果:

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

Java题解:

/** * Definition for a binary tree node.

 * public class TreeNode {

 *     int val;

 *     TreeNode left;

 *     TreeNode right;

 *     TreeNode(int x) { val = x; }* } */

class Solution {

    public TreeNode recoverFromPreorder(String S) {

        Stack<TreeNode> buffer=new Stack<TreeNode>();

        int idx=0; //遍历指针

        int slen=S.length();

        TreeNode head=new TreeNode(0);

        TreeNode nd=head;

        while(idx<slen){

            int lev=0;

            int val=0;

            while(idx<slen && S.charAt(idx)=='-'){

                ++lev;//数字前‘-’个数表示节点树深度

                ++idx;//跳过‘-’字符

            }//根据输入,如果是数字字符,则是节点值;连续数字字符是一个数

            while(idx<slen && S.charAt(idx)>='0' && S.charAt(idx)<='9'){

                val*=10; //计算出连续数字字符表示的数值

                val+=S.charAt(idx)-'0';

                ++idx;}//如果输入的树深比当前记录的节点数少,退回到树深为lev时的节点

            while(lev<buffer.size())buffer.pop();

            if(buffer.empty()==false) nd=buffer.peek();//指针回到lev层

            if(nd.left==null){//左节点为空

                nd.left=new TreeNode(val);//为其生成左子节点

                nd=nd.left; }//并走到左子节点位置

            else {//左子不空,有节点,生成右子节点

                nd.right=new TreeNode(val);

                nd=nd.right;//走到右子节点位置

            }//buffer容器存放建立过的树节点

            buffer.push(nd);}

        return head.left;}}//树从head-left开始,head头指针

Debug结果:

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

Python题解:

# Definition for a binary tree node.

# class TreeNode(object):

#     def __init__(self, x):

#         self.val = x

#         self.left = None

#         self.right = None

class Solution(object):

    def recoverFromPreorder(self, S):

        """:type S: str:rtype: TreeNode"""

        buf, idx, slen, head= [], 0, len(S), TreeNode(0)

        nd = head

        while idx<slen:

            lev, val= 0, 0

            while idx<slen and S[idx]=='-':

                lev += 1 #数字前‘-’个数表示节点树深度

                idx += 1 #/跳过‘-’字符

            #根据输入,如果是数字字符,则是节点值;连续数字字符是一个数

            while idx<slen and S[idx]>='0' and S[idx]<='9':

                val*=10 #计算出连续数字字符表示的数值

                val+=int(S[idx])

                idx += 1

            #如果输入的树深比当前记录的节点数少,退回到树深为lev时的节点

            while lev<len(buf):

                buf.pop()

            if buf:

                nd=buf[-1]#指针回到lev层

            if not nd.left:#左节点为空

                nd.left=TreeNode(val) #为其生成左子节点

                nd=nd.left #并走到左子节点位置

            else: #左子不空,有节点,生成右子节点

                nd.right=TreeNode(val)

                nd=nd.right#走到右子节点位置

            #buffer容器存放建立过的树节点

            buf.append(nd)

        return head.left#树从head-left开始,head头指针

Debug结果:

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

更多题解移步公众号免费获取

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

相关文章:

  • 2021-08-02
  • 2021-10-04
  • 2022-01-26
  • 2022-01-29
  • 2021-12-13
  • 2022-01-23
  • 2022-12-23
猜你喜欢
  • 2021-12-30
  • 2022-01-29
  • 2021-11-18
  • 2021-08-27
  • 2021-08-19
  • 2021-10-22
  • 2022-12-23
相关资源
相似解决方案