题目描述:数组
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。spa
例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。指针
先贴上完整代码:code
1 /** 2 * Definition for binary tree 3 * public class TreeNode { 4 * int val; 5 * TreeNode left; 6 * TreeNode right; 7 * TreeNode(int x) { val = x; } 8 * } 9 */ 10 public class Solution { 11 12 public TreeNode reConstructBinaryTree(int [] pre,int [] in) { 13 14 return reconstructBinaryTree(pre, 0, pre. length, in, 0, in.length); 15 } 16 17 18 private TreeNode reconstructBinaryTree(int [] pre, int preStart, int preEnd, int [] in, int inStart, int inEnd) { 19 20 if(inStart == inEnd) 21 return null; 22 23 TreeNode curRoot = new TreeNode(pre[preStart]); 24 25 for(int i = inStart; i < inEnd; i++) { 26 if (in[i] == pre[preStart]) { 27 curRoot.left = reconstructBinaryTree(pre, preStart+1, preStart+i-inStart+1, in, inStart, i); 28 curRoot.right = reconstructBinaryTree(pre, preStart+i-inStart+1, preEnd, in, i+1, inEnd); 29 break; 30 } 31 } 32 33 return curRoot; 34 } 35 }
思路:这题不难想到要用递归,难点是写递归时的一些细节,主要有2点:blog
1,对当前节点的左右子树递归时实参如何写?递归
2,递归结束条件如何写?it
对于问题1:io
只要把握前序是根左右,中序是左根右便可写出,咱们知道对左子树递归时传入的是左子树的前序数组和中序数组,那么四个位置实参就应该是class
(preStart+1, preStart+i-inStart+1, inStart, i), preStart+1不难理解,前序是根左右嘛,那么preStart+1确定是当前树的左子树的前序数组的起始位置, 接着左子树前序数组的结尾index怎么写呢?咱们只要知道了左子树中节点个数,那么当前preStart+节点个数+1就是结束index了(个人写法是数组包含起始指针,不包含结束指针),又由于中序遍历是左根右,因此节点个数等于 i - inStart,其中i是当前根节点在当前中序数组中的index,因此左子树的结尾index即 preStart+i-inStart+1,同理能够写出其它位置参数,二叉树
对于问题2:
能够想出子树中没有节点时就能够直接return null了,而子树中节点的个数就等于递归时传入的 前序数组的结束index - 前序数组的起始index = 中序数组的结束index - 中序数组的起始index , 由于2个同样,因此只要拿一个来判断就好了,如if (inEnd - inStart <= 0) return null; 可是其实写 if (inEnd - inStart == 0) 就行,由于从刚才写出的位置参数能够推出第一次不知足条件时子树的节点个数必定为0.