Skip to content

Latest commit

 

History

History
148 lines (117 loc) · 4.99 KB

README.md

File metadata and controls

148 lines (117 loc) · 4.99 KB

题目描述

我们从二叉树的根节点 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]

提示:

  • 原始树中的节点数介于 11000 之间。
  • 每个节点的值介于 110 ^ 9 之间。

标签: 树、深度优先搜索

思路 0

主要就是根据先序遍历如何把树构建出来,其最主要就是找到当前待插入节点它爹,优先插入到它爹的左子节点,我们可以用一个链表来做辅助,该链表索引代表层级,元素存放其节点,由于是先序遍历(根-左-右),也就是右覆盖左时,此时左树已遍历完成,故无需考虑覆盖问题,利用该链表,我们根据层级便可轻松找到它爹,具体如下所示:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public TreeNode recoverFromPreorder(String S) {
        char[] chars = S.toCharArray();
        int len = chars.length;
        List<TreeNode> levels = new LinkedList<>();
        for (int i = 0; i < len; ) {
            int level = 0, val = 0;
            while (chars[i] == '-') { // 获取所在层级,Character.isDigit() 会比较慢
                ++i;
                ++level;
            }
            while (i < len && chars[i] != '-') { // 获取节点的值
                val = val * 10 + chars[i++] - '0';
            }
            TreeNode curNode = new TreeNode(val);
            if (level > 0) {
                TreeNode parent = levels.get(level - 1);
                if (parent.left == null) { // 如果节点只有一个子节点,那么保证该子节点为左子节点。
                    parent.left = curNode;
                } else {
                    parent.right = curNode;
                }
            }
            levels.add(level, curNode); // 因为是先序遍历(根-左-右),也就是右覆盖左时,此时左树已遍历完成,故无需考虑覆盖问题
        }
        return levels.get(0);
    }
}

思路 1

基于上面的思路,其实我们没有必要把所有层级都保存下来,由于是先序遍历,在找待插入节点它爹时,我们可以把不小于它层级的元素都删除,基于此,用一个辅助栈便可完成寻爹之旅,具体如下所示:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public TreeNode recoverFromPreorder(String S) {
        char[] chars = S.toCharArray();
        int len = chars.length;
        LinkedList<TreeNode> stack = new LinkedList<>();
        for (int i = 0; i < len; ) {
            int level = 0, val = 0;
            while (chars[i] == '-') { // 获取所在层级,Character.isDigit() 会比较慢
                ++i;
                ++level;
            }
            while (i < len && chars[i] != '-') { // 获取节点的值
                val = val * 10 + chars[i++] - '0';
            }
            TreeNode curNode = new TreeNode(val);
            while (stack.size() > level) { // 栈顶不是父亲,栈顶出栈
                stack.removeLast();
            }
            if (level > 0) {
                TreeNode parent = stack.getLast();
                if (parent.left == null) { // 如果节点只有一个子节点,那么保证该子节点为左子节点。
                    parent.left = curNode;
                } else {
                    parent.right = curNode;
                }
            }
            stack.addLast(curNode);
        }
        return stack.get(0);
    }
}

结语

如果你同我一样热爱数据结构、算法、LeetCode,可以关注我 GitHub 上的 LeetCode 题解:awesome-java-leetcode