LeetCode105: Construct Binary Tree from Preorder and Inorder Traversal(從前序與中序遍歷序列構造二叉樹)

Given preorder and inorder traversal of a tree, construct the binary tree.

Note:
You may assume that duplicates do not exist in the tree.

For example, given

preorder = [3,9,20,15,7]
inorder = [9,3,15,20,7]

Return the following binary tree:

    3
   / \
  9  20
    /  \
   15   7

思路

  • 二叉樹的前序遍歷特徵:首個元素爲根,然後是左子樹和右子樹

  • 二叉樹中序遍歷特徵:先是左子樹,然後根,最後是右子樹

  • 因此可以先根據前序遍歷中根的值,找到中序遍歷根的索引, 這樣就可以在中序遍歷中找到左右子樹。

  • 然後採用遞歸的思路,從葉子結點開始依次往上遞歸建樹,遞歸出口爲:當節點爲葉子節點或樹爲空時。

Java實現

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        return preIn(preorder, 0, preorder.length-1, inorder, 0, inorder.length-1);
    }
    public static TreeNode preIn(int[] preorder, int preLeft, int preRight, int[] inorder, int inLeft, int inRight) {
        if (preorder.length == 0) {
            return null;
        }
        // 創建根節點
        TreeNode root = new TreeNode(preorder[preLeft]);
        root.left = null;
        root.right = null;
        // 存儲左子樹的長度
        int leftLength = 0;
        // 存儲右子樹的長度
        int rightLength = 0;
        // 尋找左右子樹長度
        for (int i = inLeft; i < inRight+1; i++) {
            if (inorder[i] == root.val) {
                leftLength = i- inLeft;
                rightLength = inRight - inLeft + 1 - leftLength -1;
                break;
            }
        }
        if (leftLength > 0) {
            root.left = preIn(preorder, preLeft+1, preLeft+1+leftLength-1, inorder, inLeft, inLeft+leftLength-1);
        }
        if (rightLength > 0) {
            root.right = preIn(preorder, preLeft+1+leftLength, preRight, inorder, inLeft+leftLength-1+2, inRight);
        }
        return root;
    }
}

Python實現

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def buildTree(self, preorder, inorder):
        """
        :type preorder: List[int]
        :type inorder: List[int]
        :rtype: TreeNode
        """
        return self.preIn(preorder, 0, len(preorder)-1, inorder, 0, len(inorder)-1)
    
    def preIn(self, preorder, preLeft, preRight, inorder, inLeft, inRight):
        """
        :type preorder: List[int]
        :type preLeft: int
        :type preRight: int
        :type inorder: List[int]
        :type inLeft: int
        :type inRight: int
        :rtype: TreeNode
        """
        if len(preorder) == 0:
            return None
        
        # 創建節點
        root = TreeNode(preorder[preLeft])
        # 定義左子樹的長度
        leftLength = 0
        # 定義右子樹的長度
        rightLength = 0
        # 計算左右子樹的長度
        for i in range(inLeft, inRight+1):
            if inorder[i] == root.val:
                leftLength = i - inLeft
                rightLength = inRight - inLeft + 1 - leftLength - 1
                break
        
        # 構建左子樹
        if leftLength > 0:
            root.left = self.preIn(preorder, preLeft+1, preLeft+1+leftLength-1, inorder, inLeft, inLeft+leftLength-1)
        
        # 構建右子樹
        if rightLength > 0:
            root.right = self.preIn(preorder, preLeft+1+leftLength, preRight, inorder, inLeft+leftLength-1+2, inRight)

        return root

Scala實現

/**
 * Definition for a binary tree node.
 * class TreeNode(var _value: Int) {
 *   var value: Int = _value
 *   var left: TreeNode = null
 *   var right: TreeNode = null
 * }
 */
object Solution {
    def buildTree(preorder: Array[Int], inorder: Array[Int]): TreeNode = {
        return preIn(preorder, 0, preorder.length-1, inorder, 0, inorder.length-1)
    }

    def preIn(preorder: Array[Int], preLeft: Int, preRight: Int, inorder: Array[Int], inLeft: Int, inRight: Int): TreeNode = {
        if (preorder.length == 0) {
            return null
        }

        // 創建節點
        val root = new TreeNode(preorder(preLeft))
        // 存儲左子樹的長度
        var leftLength = 0
        // 存儲右子樹的長度
        var rightLength = 0
        // 尋找左右子樹的長度
        for (i <- inLeft to inRight) {
            if (inorder(i) == root.value) {
                leftLength = i - inLeft
                rightLength = inRight - inLeft + 1 - leftLength - 1
            }
        }

        if (leftLength > 0) {
            root.left = preIn(preorder, preLeft+1, preLeft+1+leftLength-1, inorder, inLeft, inLeft+leftLength-1)
        }
        if (rightLength > 0) {
            root.right = preIn(preorder, preLeft+1+leftLength, preRight, inorder, inLeft+leftLength-1+2, inRight)
        }

        return root
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章