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);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章