DailyChallenge
1028. 从先序遍历还原二叉树
Hard20200618
题目描述
我们从二叉树的根节点 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-cn.com/problems/re…
Solution
我们每次从字符串 ss 中取出一个节点的值以及它的深度信息。具体地:
- 我们首先读取若干个字符 -,直到遇到非 - 字符位置。通过 - 的个数,我们就可以知道当前节点的深度信息;
- 我们再读取若干个数字,直到遇到非数字或者字符串的结尾。通过这些数字,我们就可以知道当前节点的值。
得到这些信息之后,我们就需要考虑将当前的节点放在何处。记当前节点为 TT,上一个节点为 SS,那么实际上只有两种情况:
- T 是 S 的左子节点;
- T是根节点到 SS 这一条路径上(不包括 SS)某一个节点的右子节点。
我们只需要借助一个栈,通过迭代的方法就可以还原出这棵二叉树。
/**
* 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) {
Deque<TreeNode> path = new LinkedList<>();
int num = 0;
while(num < s.length()){
int lev = 0, val = 0;
while(s.charAt(num) == '-'){
lev++;
num++;
}
while(num < s.length() && Character.isDigit(s.charAt(num))){
val = val * 10 + s.charAt(num) - '0';
num++;
}
TreeNode temp = new TreeNode(val);
if(path.size() == lev){
if(!path.isEmpty()){
path.peek().left = temp;
}
}else{
while(lev != path.size()){
path.pop();
}
path.peek().right = temp;
}
path.push(temp);
}
while (path.size() > 1) {
path.pop();
}
return path.peek();
// return path.peekFirst();
}
}
参考官方题解
❝我的公众号:GitKid
暂时每日分享LeetCode,我在不断学习的过程中,公众号也在不断充实,欢迎大家扫码关注。
TODO:《剑指offer》系列

本文使用 mdnice 排版