剑指offer第二版——面试题7(java)

面试题7:重建二叉树

 

题目描述: 
输入某二叉树的前序遍历和中序遍历的结果,请重新构造出该二叉树。假设输入的前序遍历和中序遍历的结果中不包含重复的数字。例如输入的前序遍历序列为{1,2,4,7,3,5,6,8}和中序遍历为{4,7,2,1,5,3,6,8},则重建出二叉树并输出它的头结点

(head.Too(head)——是ListNode中写的一个递归的前序遍历)

代码:

// 2019-06-14
public class Q7 {
	public static void main(String[] args) {
		int[] a = new int[] {1,2,3,5,7};
		int[] b = new int[] {5,3,2,4,1};
		BinaryTreeNode root = getTree(a, b);
	}
	
	public static BinaryTreeNode getTree(int[] a,int[] b) {
		// 数组中只有一个数字,直接返回该节点
		if(a.length==1) {
			if(a[0]==b[0]) {
				return new BinaryTreeNode(a[0]);
			}else {
				System.out.println("not same tree\n");
				return null;
			}
		}
		
		// 数组为空,则返回null
		if(a.length==0) {
			return null;
		}
		
		// 对数组构建子树/树
		BinaryTreeNode head = new BinaryTreeNode(a[0]);
		
		// 寻找左右子树划分点
		int index = findLoc(a[0], b);
		
		// 如果划分点未出现在b中,则表示两个数组不同,不是一棵树的遍历
		if(index==-1) {
			return null;
		}
		
		// 分别对左子树和右子树进行构建
		head.left = getTree(Arrays.copyOfRange(a, 1, index+1), Arrays.copyOfRange(b, 0, index));
		head.right = getTree(Arrays.copyOfRange(a, index+1, a.length), Arrays.copyOfRange(b, index+1, b.length));

		return head;
	}

	
	// 在数组中找到左右子树的划分点
	public static int findLoc(int x,int[] b) {
		for(int i=0;i<b.length;i++) {
			if(b[i]==x) {
				return i;
			}
		}
		return -1;
	}
}
// 2019-03-08
class Q7 {
	public static void main(String[] args) {
		int[] l1 = new int[] {1,2,4,7,3,5,6,8};
		int[] l2 = new int[] {4,7,2,1,5,3,8,6};
		ListNode head = rebuild(l1,l2);
		System.out.println("------");
		head.Too(head);
		
	}  
	
	public static ListNode rebuild(int[] l1,int[] l2) {
		ListNode head = null;
		if(l1!=null && l2!=null &l1.length==l1.length&&l1.length!=0){
			head = new ListNode(l1[0]);
			rebuildTree(head,l1,l2);
		}else {
			return null;
		}
		return head;
	}
	
	public static void rebuildTree(ListNode head,int[] l1,int[] l2){
		if(l1!=null && l2!=null) {
			if(l1.length==l2.length && l1.length!=0) {
				int loc = findloc(l1[0],l2);
				
				int[] left1=null,left2=null,right1=null,right2=null;
				
				// 下一次的左右
				if(loc!=0) {
					left1 = Arrays.copyOfRange(l1, 1, loc+1);
					left2 = Arrays.copyOfRange(l2, 0, loc);
					head.left = new ListNode(left1[0]);
				}
				if(loc!=l1.length-1) {
					right1 = Arrays.copyOfRange(l1, loc+1, l1.length);
					right2 = Arrays.copyOfRange(l2, loc+1, l2.length);	
					head.right = new ListNode(right1[0]);
				}

				rebuildTree(head.left,left1,left2);
				rebuildTree(head.right, right1, right2);
			}
		}	
	}
	
	public static int findloc(int x,int[] l2) {
		int loc=0;
		for(int i=0;i<l2.length;i++) {
			if(l2[i]==x) {
				loc = i;
				return loc;
			}
		}
		return -1;
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值