105.Construct Binary Tree from Preorder and Inorder Traversal---《剑指offer》面试6
题目大意:根据先序遍历和中序遍历构造二叉树。
法一:DFS。根据模拟步骤,直接从先序和中序数组中找值然后加入二叉树中,即先从先序数组中确定根结点,然后再去中序数组中确定左子树和右子树的长度,然后根据左子树和右子树的长度,去划分先序数组和中序数组,确定左子树和右子树。代码如下(耗时15ms):
1 public TreeNode buildTree(int[] preorder, int[] inorder) { 2 if(preorder.length == 0 || inorder.length == 0) { 3 return null; 4 } 5 return dfs(preorder, inorder, 0, preorder.length - 1, 0, inorder.length - 1); 6 } 7 //preL是当前先序数组的第一个结点下标,preR是当前先序数组的最后一个结点下标 8 //inL是当前后序数组的第一个结点下标,inR是当前后序数组的最后一个结点下标 9 private TreeNode dfs(int[] preorder, int[] inorder, int preL, int preR, int inL, int inR) { 10 //将当前先序数组的第一个结点加入二叉树中,这个结点其实就是当前子树的根节点 11 TreeNode root = new TreeNode(preorder[preL]); 12 //根据这个根节点,去中序数组中找到位置下标 13 int rootIndex = inL; 14 while(inorder[rootIndex] != preorder[preL]) { 15 rootIndex++; 16 } 17 //左子树长度,根据当前中序数组和刚才确定的根节点下标,计算左子树长度,即中序数组中根节点前面的则是左子树 18 int leftLen = rootIndex - inL; 19 //右子树长度,根据当前中序数组和刚才确定的根节点下标,计算右子树长度,即中序数组中根节点后面的则是右子树 20 int rightLen = inR - rootIndex; 21 if(leftLen != 0) { 22 //确定左子树 23 root.left = dfs(preorder, inorder, preL + 1, preL + leftLen, inL, inL + leftLen - 1); 24 } 25 else { 26 root.left = null; 27 } 28 if(rightLen != 0) { 29 //确定右子树 30 root.right = dfs(preorder, inorder, preR - rightLen + 1, preR, inR - rightLen + 1, inR); 31 } 32 else { 33 root.right = null; 34 } 35 return root; 36 }