持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第16天,点击查看活动详情
今天,我们继续搞算法。
题目描述
给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。
题目分析
这个题目是让我们构造二叉树并返回其根节点。
输入: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7] 输出: [3,9,20,null,null,15,7]
我们对结果进一步分析: preorder中可以看出根是3,inorder可以看出根是3,左子树是9, preorder中可以看出右子树是20,对应的根是20,左子树是15,右子树是7 进而还原整颗树。
解题思路
- 确定操作对象:本题中,操作对象1个root
- 确定操作条件:如果对象为空,返回空,如果遍历完了,返回空。
- 确定操作过程:操作过程为,根据前序遍历和中序遍历特点,依次取出根和左右孩子,递归还原整棵树。
- 确定结果返回:返回最终结果。
代码
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
/**
* 我们先来分析一下这个条件,给定前序和中序分别如下:
* preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
* 我们要的结果是[3,9,20,null,null,15,7],3为根,9和20为其左右子树,依次类推。
* 根据前序特点,preorder的0号元素为根,左右子树是从1号元素开始,到哪呢?从前序看不出来。
* 因此,我们看中序,我们找到根,是1号元素,那一号元素之前是不是左子树?,同理我们可以还原出整棵树
* 依次这么找,就还原了整棵树,最后把根节点返回皆可。
*/
class Solution {
public TreeNode buildTree(int[] preorder, int[] inorder) {
this.preorder = preorder;
this.inorder = inorder;
return build(0,preorder.length-1,0,inorder.length-1);
}
public TreeNode build(int pstart ,int pend , int istart, int iend){
int imid=istart;
if(pstart>pend) return null;
TreeNode root = new TreeNode(preorder[pstart]);
if(root == null) return null;
while(inorder[imid] != root.val){
imid++;
}
root.left = build(pstart+1,pstart+(imid-istart),istart,imid-1);
root.right = build(pstart+(imid-istart)+1,pend,imid+1,iend);
return root;
}
int[] preorder;
int[] inorder;
}