在刷面试算法题,见到有大神的代码灰常简洁,灰常牛B,拿过来膜拜一下
public class Solution {
public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
TreeNode root=reConstructBinaryTree(pre,0,pre.length-1,in,0,in.length-1);
return root;
}
//前序遍历{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6}
private TreeNode reConstructBinaryTree(int [] pre,int startPre,int endPre,int [] in,int startIn,int endIn) {
if(startPre>endPre||startIn>endIn)
return null;
TreeNode root=new TreeNode(pre[startPre]);
for(int i=startIn;i<=endIn;i++)
if(in[i]==pre[startPre]){
root.left=reConstructBinaryTree(pre,startPre+1,startPre+i-startIn,in,startIn,i-1);
root.right=reConstructBinaryTree(pre,i-startIn+startPre+1,endPre,in,i+1,endIn);
}
return root;
}
}
大神把递归用得如此出神入化,我最主要记录下
root.left=reConstructBinaryTree(pre,startPre+1,startPre+i-startIn,in,startIn,i-1);
root.right=reConstructBinaryTree(pre,i-startIn+startPre+1,endPre,in,i+1,endIn);
这两句的理解:
每一次的递归都分开左子树和右子树来生成,先来第一句
startPre+1:因为先序序列的第一个数就是根节点,所以第一次递归让先序序列的开始下标+1
startPre+i-startIn:然后看中序序列的根节点在哪个位置,那个位置就是i,把先序序列中的开始下标+i(所有左子树的个数)减去中序序列的开始下标(减去上一些根节点的左子树),就是这一段子树的尾端
startIn:因为中序序列的第一个值不是根,所以直接取该开始下标
i-1:因为i是根在中序序列的位置,所以要减去一
i-startIn+startPre+1:右子树中,因为有可能之前迭代过几次,所以i不一定对应正确的位移,所以让i-startIn得出这一个右子树中左子树的量,然后加一,因为第一个数是根嘛
endPre:直接取先序序列中的尾端,因为这个根结点右边的都是该结点右子树
i+1:中序序列中,直接+1,因为i是根节点,根节点右边开始都属于右子树
endIn:同理直接取中序序列的末尾下标
表达能力有点不足,也不知道过一段时间还能不能看懂自己写的东西哈哈~