您的位置:首页 > 其它

个人记录-LeetCode 105. Construct Binary Tree from Preorder and Inorder Traversal

2017-04-27 16:53 591 查看
问题:

Given preorder and inorder traversal of a tree, construct the binary tree.

Note:

You may assume that duplicates do not exist in the tree.

这个问题的条件就是:

给你两个数组,

分别保存一个树先序遍历得到的值,

及该树中序遍历得到的值。

现在要求根据这两个数组,重构出这个树。

解决这个问题,关键是找出数组和树之间的联系。

5
/   \
2     7
/ \   / \
1   3  6  9


例如上面这颗树,

它先序遍历形成的数组为: 5 2 1 3 7 6 9

它中序遍历形成的数组为: 1 2 3 5 6 7 9

比对数组和树可以发现:

先序遍历的第一个数,对应着根节点的值,

在上述的例子中是5;

在中序遍历后的数组中,5的左侧就根节点的左子树;

5的右侧就是根节点的右子树。

根据中序遍历数组,知道1 2 3构成根节点的左子树后,

我们可以从先序遍历数组中,找出对应的2 1 3。

此时,2 1 3就是根节点左子树的先序遍历;

1 2 3是根节点左子树的中序遍历。

因此,可以按同样的规则,

利用2 1 3和1 2 3构造出左子树。

同理,对于根节点的右子树也可以利用7 6 9和6 7 9构造。

按照上述的思路,就可以递归得到整个树。

代码示例:

/**
* Definition for a binary tree node.
* public class TreeNode {
*     int val;
*     TreeNode left;
*     TreeNode right;
*     TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public TreeNode buildTree(int[] preorder, int[] inorder) {
//首先判断preorder和inorder数组是否有效
if (preorder == null || inorder == null) {
return null;
}

if (preorder.length != inorder.length || preorder.length == 0) {
return null;
}

//preorder的第一个数对应根节点
int rootVal = preorder[0];
TreeNode root = new TreeNode(rootVal);

//判断inorder中,根节点左侧有个数
int count = 0;
for (int i : inorder) {
if (i == rootVal) {
break;
}
++count;
}

if (count > 0) {
int[] preorderLeft = new int[count];
int[] inorderLeft = new int[count];

//preorderLeft保存先序遍历,根节点左侧的值
System.arraycopy(preorder, 1, preorderLeft, 0, count);

//inorderLeft保存中序遍历,根节点左侧的值
System.arraycopy(inorder, 0, inorderLeft, 0, count);

//递归构造出左子树
root.left = buildTree(preorderLeft, inorderLeft);
}

//得到右子树节点数量
int rest = preorder.length - count - 1;
if (rest > 0) {
int[] preorderRight = new int[rest];
int[] inorderRight = new int[rest];

//preorderRight保存先序遍历,根节点右侧的值
System.arraycopy(preorder, count + 1, preorderRight, 0, rest);

//inorderRight 保存中序遍历,根节点右侧的值
System.arraycopy(inorder, count + 1, inorderRight, 0, rest);

//递归构造出右子树
root.right = buildTree(preorderRight, inorderRight);
}

return root;
}
}


当然,我这里为了复用buildTree的接口,增加了拷贝的操作,显得比较耗时一些。

也可以新增一个递归接口,传入整个数组及每次生成树用到的序号范围。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐