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
    }
}

你可能感兴趣的:(LeetCode)