We run a preorder depth first search on the root
of a binary tree.
At each node in this traversal, we output D
dashes (where D
is the depth of this node), then we output the value of this node. (If the depth of a node is D
, the depth of its immediate child is D+1
. The depth of the root node is 0
.)
If a node has only one child, that child is guaranteed to be the left child.
Given the output S
of this traversal, recover the tree and return its root
.
Example 1:
Input: "1-2--3--4-5--6--7" Output: [1,2,5,3,4,6,7]
Example 2:
Input: "1-2--3---4-5--6---7" Output: [1,2,5,3,null,6,null,4,null,7]
Example 3:
Input: "1-401--349---90--88" Output: [1,401,null,349,88,90]
Note:
- The number of nodes in the original tree is between
1
and1000
. - Each node will have a value between
1
and10^9
.
从先序遍历还原二叉树。
我们从二叉树的根节点 root 开始进行深度优先搜索。
在遍历中的每个节点处,我们输出 D 条短划线(其中 D 是该节点的深度),然后输出该节点的值。(如果节点的深度为 D,则其直接子节点的深度为 D + 1。根节点的深度为 0)。
如果节点只有一个子节点,那么保证该子节点为左子节点。
给出遍历输出 S,还原树并返回其根节点 root。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/recover-a-tree-from-preorder-traversal
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路不难,但是实现起来会有一些细节值得注意。我这里给出的是迭代的做法。
既然是前序遍历的迭代,一般会用到一个stack。遍历input,如果遇到数字就试着把数字结算出来,存成节点;如果是横线,则是用来记录当前树的深度level的。
- 如果当前level等于stack的size,则说明刚刚结算出来的node是stack顶端节点的左孩子
- 如果当前level不等于stack的size,则说明刚刚结算出来的node是stack顶端节点的右孩子,同时stack顶端节点需要pop出来
- stack里面最后一个节点是树的root
时间O(n)
空间O(n)
Java实现
1 /** 2 * Definition for a binary tree node. 3 * public class TreeNode { 4 * int val; 5 * TreeNode left; 6 * TreeNode right; 7 * TreeNode() {} 8 * TreeNode(int val) { this.val = val; } 9 * TreeNode(int val, TreeNode left, TreeNode right) { 10 * this.val = val; 11 * this.left = left; 12 * this.right = right; 13 * } 14 * } 15 */ 16 class Solution { 17 public TreeNode recoverFromPreorder(String S) { 18 Deque<TreeNode> path = new ArrayDeque<>(); 19 int pos = 0; 20 while (pos < S.length()) { 21 int level = 0; 22 while (S.charAt(pos) == '-') { 23 level++; 24 pos++; 25 } 26 int value = 0; 27 while (pos < S.length() && Character.isDigit(S.charAt(pos))) { 28 value = value * 10 + (S.charAt(pos) - '0'); 29 pos++; 30 } 31 TreeNode node = new TreeNode(value); 32 if (level == path.size()) { 33 if (!path.isEmpty()) { 34 path.peek().left = node; 35 } 36 } else { 37 while (level != path.size()) { 38 path.pop(); 39 } 40 path.peek().right = node; 41 } 42 path.push(node); 43 } 44 while (path.size() > 1) { 45 path.pop(); 46 } 47 return path.peek(); 48 } 49 }