我们从二叉树的根节点 root 开始进行深度优先搜索。
在遍历中的每个节点处,我们输出 D 条短划线(其中 D 是该节点的深度),然后输出该节点的值。(如果节点的深度为 D,则其直接子节点的深度为 D + 1。根节点的深度为 0)。
如果节点只有一个子节点,那么保证该子节点为左子节点。
给出遍历输出 S,还原树并返回其根节点 root。
题解:
1.字符串还原二叉树
2.输入中数字前的划线D 条短划线表示节点深度为D
3.根节点的深度为 0
4.节点只有一个子节点,该子节点为左子节点
示例 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 之间
解题思路:
-
由于规定是先序遍历还原二叉树,先序遍历先根节点,不断遍历左子节点,再遍历右子节点
-
分开几记录节点深度和节点值,节点值通过字符数字转换过去
-
使用一个临时容器存放生成的节点
-
如果节点深度小于容器中建成的树节点,则把工作指针回退到节点深度层上,对容器不断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结果:
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结果:
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结果:
更多题解移步公众号免费获取