题目链接:从先序遍历还原二叉树
题目描述:
我们从二叉树的根节点 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 之间。
题目分析:对于给出的字符串S,分隔符是一个很好的入手点,根据分隔符能够很快划分出二叉树的左右子树
比如字符串:1-2–3—4-5–6—7
根据- 分为 根1 左子树 2--3--4 右子树5--6--7
继续根据-- 左左子树分为 根2 左子树3 右子树 4
右右子树同理 根5 左6 右7
不难看出,这是个递归处理的过程,比较麻烦的点就是字符串的拆分了,拆分好之后递归处理即可
利用正则表达式进行处理
这里注意一个点,我代码中使用的方式有一个特点,当2--3--4,以--进行拆分时,会拆成2,3--4,
这样2--3--4与2--3---4的这样拆的话得到的结果是一样的,那么需要再次处理一下,看代码吧
class Solution {
public TreeNode recoverFromPreorder(String S) {
TreeNode root = reviviTree(1, S);
return root;
}
private TreeNode reviviTree(int layer,String str){
if(str.equals("")) return null;
String regex = "";
//深度生成分隔符
for(int i = 0;i < layer;i++) regex += '-';
//根据分隔符拆分
str=str.replaceAll("([0-9])"+regex+"([0-9])","$1,$2");
String[] nodes = str.split(",");
TreeNode root = new TreeNode(Integer.valueOf(nodes[0]));
// System.out.println(str+" "+regex+" "+nodes.length);
String leftStr = "",rightStr = "";
//2,3--4形式需要再次处理
if(nodes.length==2){
nodes[1]=nodes[1].replaceAll("([0-9])"+regex+"([0-9])","$1,$2");
String[] te = nodes[1].split(",");
if(te.length>1){//左右均有
leftStr = te[0];
rightStr = te[1];
}else{//只有左子树
leftStr = te[0];
rightStr = "";
}
root.left = reviviTree(layer+1, leftStr);
root.right = reviviTree(layer+1, rightStr);
}
//1,2--3--4,5--6--7形式直接传递即可
if(nodes.length==3){
root.left = reviviTree(layer+1, nodes[1]);
root.right = reviviTree(layer+1, nodes[2]);
}
return root;
}
}
其实思路挺简单的就是一个递归,只不过字符串的处理麻烦了些。。。。。。天啊,给我一个万能的工具吧