剑指offer(牛客)---4.重建二叉树

题目描述

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

做这道题之前一定要对前序遍历和中序遍历非常理解,刚开始由于我没有很好的理解他们,画图的时候一直卡着,差点以为是题目的例子错了,不过后来很好,看了朋友画的图反应过来了;

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

这道题主要是你得有node的结点意识,每个点往下层又是一个root结点;以这种思想然后进行递归,问题就很好解决了;

首先对例子进行分析:

前序遍历序列{1,2,4,7,3,5,6,8}

中序遍历序列{4,7,2,1,5,3,8,6}

这里面你首先根据前序遍历可知道root结点是1,然后又根据中序遍历你可以知道1左边的都是root根结点的左孩子群{4,7,2},1右边的都是root根结点的右孩子群{5,3,8,6};

根据上面我们可以画出第一个结点:

这样你可以先进入root根结点的左孩子群里面;root(1)的左孩子是2,在这里你就得把左孩子直接看成一个root根结点,其他的暂时都不用想,这样的话,以root根结点来看它的:

前序遍历序列{2,4,7}

中序遍历序列{4,7,2}

这里面你又根据前序遍历可知道root结点是2,然后根据中序遍历你可以知道2左边的都是root(2)根结点的左孩子群,2右边没有,说明没有右孩子群;

根据上面我们可以画出第二个结点:

你又进入到root(2)的左孩子群里面,以4作为根结点继续:

前序遍历序列{4,7}

中序遍历序列{4,7}

以4做为root(4)结点,根据中序遍历发现它没有左孩子只有一个右孩子,那么在这里开始遍历它的右子树,得出它俩如下的位置:

回到上一个的右子树群,一直追溯回去发现,也就只剩下是root(1)的右子树没有遍历了,然后直接又以右子树建立前序遍历和中序遍历:

前序遍历序列{3,5,6,8}

中序遍历序列{5,3,8,6}

根据前序遍历的性质,以root(3)为根结点,由中序遍历可知3左边的{5}为左孩子群,{8,6}为右孩子群;现在可以又可以确定一个结点:

以root(3)为根简单分析它的左孩子群:

前序遍历序列{3,5}

中序遍历序列{5,3}

根据中序遍历可知5是root(3)的左孩子,root(3)没有右孩子,又可以画出一个结点:

由于root(5)已经没有左孩子和右孩子了,又回到root(3)分析它的右孩子:

前序遍历序列{6,8}

中序遍历序列{8,6}

根据前序遍历root(6)为根结点,根据中序遍历root(6)左边的为左孩子群,右边的为右孩子群(很显然它没有右孩子群)

进入root(6)的左孩子群,直接得出左孩子结点为8,画出最终图像:

下面贴出代码:

/**
 * Definition for binary tree
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
import java.util.*;
public class Solution {
    public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
        if(pre.length==0||in.length==0) {
			return null;
		}
		TreeNode node=new TreeNode(pre[0]);
		if(pre.length==1||in.length==1) {
			return node;
		}
		for(int i=0;i<pre.length;i++) {
			if(pre[0]==in[i]) {
				node.left=reConstructBinaryTree(Arrays.copyOfRange(pre, 1, i+1),Arrays.copyOfRange(in, 0, i));
				node.right=reConstructBinaryTree(Arrays.copyOfRange(pre, i+1, pre.length),Arrays.copyOfRange(in, i+1, in.length));
			}
		}
		return node;
    }
}

 理解上面解题的思维,程序其实并不难,只是几行代码加上两个递归;对于二叉树一定要以结点的思想去思考,这样会更容易理解.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值