解法一
参考了评论区的思路。先解析字符串,提取每个结点的信息,然后按顺序建树,根据深度信息判断是否进一步建立子结点。
也可以一边遍历一边解析字符串,总体类似。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
// 结点深度队列
private Queue<Integer> depthQueue;
// 结点数值队列
private Queue<Integer> numQueue;
public TreeNode recoverFromPreorder(String S) {
depthQueue = new LinkedList<>();
numQueue = new LinkedList<>();
// 当前结点的深度信息在S中的起始下标
int depthHead = 0;
for (int i = 0; i < S.length(); ) {
// 解析深度
while (S.charAt(i) == '-') {
++i;
}
depthQueue.offer(i - depthHead);
// 解析数值
int num = 0;
while ((i < S.length()) && (S.charAt(i) != '-')) {
num = num * 10 + S.charAt(i) - 48;
++i;
}
numQueue.offer(num);
depthHead = i;
}
if (depthQueue.isEmpty()) {
return null;
}
return build(0);
}
/**
* 建树
*
* @param depth 当前深度
* @return 该深度结点
*/
private TreeNode build(int depth) {
if ((depthQueue.isEmpty()) || (depthQueue.peek() != depth)) {
return null;
}
depthQueue.poll();
TreeNode root = new TreeNode(numQueue.poll());
// 左子树优先于右子树
// 根据题中字符串的性质, 没有左子树一定也没有右子树
root.left = build(depth + 1);
root.right = build(depth + 1);
return root;
}
}