zoukankan      html  css  js  c++  java
  • [LeetCode] 1028. Recover a Tree From Preorder Traversal

    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 and 1000.
    • Each node will have a value between 1 and 10^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 }

    LeetCode 题目总结

  • 相关阅读:
    第二阶段冲刺01
    第十三周进度条
    构建之法阅读笔记5
    水王2
    购买一批书的最低价格
    第十二周进度条
    个人工作总结08
    个人工作总结07
    人机交互设计分析之搜狗输入法
    第八周的学习进度条
  • 原文地址:https://www.cnblogs.com/cnoodle/p/13155583.html
Copyright © 2011-2022 走看看