算法之不按期更新(四)—— 從前序與中序遍歷序列構造二叉樹(2018-06-02)

從前序與中序遍歷序列構造二叉樹

今天帶來的是Leetcode上的一個經典題:從前序與中序遍歷序列構造二叉樹
原題幹:node

/**算法

  • Definition for a binary tree node.
  • function TreeNode(val) {
  • this.val = val;
  • this.left = this.right = null;
  • }

*/
/**ui

  • @param {number[]} preorder
  • @param {number[]} inorder
  • @return {TreeNode}

*/
input:this

  • 前序遍歷 preorder = [3,9,20,15,7]
  • 中序遍歷 inorder = [9,3,15,20,7]

output: 樹的根節點spa

條件:
樹的結構爲:{ val, left, right }code

下面是我解決這個題的時候的思路blog





















解題思路

這個題目考察的是對樹結構和樹遍歷的熟悉程度。樹的前序,中序遍歷的結構以下圖:遞歸

clipboard.png

能夠看出,經過前序遍歷能夠肯定根節點,再經過中序遍歷和根節點的位置能夠肯定出左子樹和右子樹。另外左子樹的前序遍歷和中序遍歷的順序跟在其父樹中的順序同樣。ip

所以能夠肯定有一種遞歸解法。肯定根和左右子樹,遞歸用左右子樹的前序和中序順序去獲取左右子樹。leetcode

代碼

var buildTree = function(preorder, inorder) {
    if (preorder.length === 0) {
        return null
    }
    let leftTreeLen = 0
    let rightTreeLen = 0
    let tag = 1
    for (let i = inorder.length - 1; i >= 0; i--) {
        if (inorder[i] !== preorder[0]) {
            if (tag) {
                rightTreeLen++
            } else {
                leftTreeLen++
            }
        } else if (inorder[i] === preorder[0]) {
            tag = false
        }
    }
    let root = new TreeNode(preorder[0]) // 根
    root.left = buildTree(preorder.slice(1, 1 + leftTreeLen), inorder.slice(0, leftTreeLen))
    root.right = buildTree(preorder.slice(1 + leftTreeLen), inorder.slice(-rightTreeLen))
    return root
};

晚上再更新一次,目測是有非遞歸的解法的。


本期算法小分享就到這裏咯(leetcode正在作完探索裏的中級。)若是有什麼意見或者想法歡迎在評論區和我交流

相關文章
相關標籤/搜索