JavaScript:leetcode_1028. 从先序遍历还原二叉树

题目说明

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

解题思路一(S转换数组,前序特性分割递归)

  1. 这道题是困难题,但是其实对二叉树稍微熟悉点的话,并不是很难,只能说麻烦一些,一共分两步,第一步处理字符串,第二步构建二叉树。
  2. 第一步首先将"1-401--349---90--88"转换成一个同顺序的节点数组arr,这样便于我们操作。
  3. 第二步构建二叉树
    1. 首先选择根节点,也就是arr的第一位,其level0
    2. 然后在arr.slice(1)中寻找level1的节点,也就是rootleftright节点。
    3. 注意题目说明:如果节点只有一个子节点,那么保证该子节点为左子节点。
    4. 也就是说我们按顺序遍历arr,第一个level1的就是rootleft节点,第二个就是right节点(最多两个)
    5. 当找到left节点时,声明left变量记录下标iright节点同样记录下标,搜索完毕之后level++
    6. [left+1,right) 为左树节点数组,[right + 1,arr.length) 为右树节点,分割递归。
    7. 然后判读root.left 是否存在,若存在 root.left && build(root.left, arr.slice(left + 1, right), level);
    8. 然后判读root.right 是否存在,若存在 root.right && build(root.right , arr.slice(right + 1), level);
    9. 当数组为空时返回。
  4. 返回root

代码实现一

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {string} S
 * @return {TreeNode}
 */
var recoverFromPreorder = function(S) {
    let levelFlag = 0;
    let arr = [];
    let num = '';
    for (let i = 0; i < S.length; i++) {
        if (S[i] === '-') {
            levelFlag++;
        } else {
            num += S[i];
            if (S[i + 1] == '-' || (i + 1) == S.length) {
                let node = new TreeNode(num);
                node.level = levelFlag;
                arr.push(node)
                levelFlag = 0;
                num = '';
            }
        }
    }
    let root = arr[0];
    build(root, arr.slice(1), 1);
    return root;
};

var build = function(root, arr, level) {
    if (!arr.length) {
        return;
    }
    let left = 0;
    let right = arr.length;
    for (let i = 0; i < arr.length; i++) {
        if (arr[i].level === level) {
            if (root.left == null) {
                root.left = arr[i];
                left = i;
            } else {
                root.right = arr[i];
                right = i;
                break;
            }
        }
    }
    level++;
    root.left && build(root.left, arr.slice(left + 1, right), level);
    root.right && build(root.right, arr.slice(right + 1), level);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章