树的题,要记住,树的题一般都有递归做法。。
对于preOrder来说,先遍历ROOT,然后往左,再往右,只能保证第一个是ROOT,其余不一定。
我们就先得到ROOT。
对于inOrder来说,如果找到了ROOT,那么遍历ROOT之前的所有Node都是左边的,之后都是右边的。
所以我们通过preOrder得到ROOT,然后在inOrder里找到ROOT,因为没有重复的,所以找到那个数就是ROOT。
在
然后0-(ROOT-1)作为左边子树再recursion
ROOT+1到尾是右边子树
构建ROOT.LEFT = ...
ROOT.RIGHT =
递归
return root 就行了。。
public TreeNode buildTree(int[] preorder, int[] inorder) {
if(preorder.length == 0) return null;
int rootIndex = 0;
int tempRootVal = preorder[rootIndex];
int tempIndex = 0;
while(inorder[tempIndex] != tempRootVal)
{
tempIndex++;
}
TreeNode root = new TreeNode(tempRootVal);
int[] newPre = Arrays.copyOfRange(preorder,rootIndex+1,tempIndex+1);
int[] newIn = Arrays.copyOfRange(inorder,rootIndex,tempIndex);
root.left = buildTree(newPre,newIn);
newPre = Arrays.copyOfRange(preorder,tempIndex+1,preorder.length);
newIn = Arrays.copyOfRange(inorder,tempIndex+1,inorder.length);
root.right = buildTree(newPre,newIn);
return root;
}
代码比较简单,搞好INDEX就没问题了。。可以写在纸上。
一开始从尾找,比较麻烦,如果用这种思路,不如从头找。
然后好像可以用STACK来做 还没看 二刷看看。。
二刷。
每次找ROOT,然后肥城两边就行了。
public class Solution
{
public TreeNode buildTree(int[] pre, int[] in)
{
if(pre.length == 0) return null;
if(pre.length == 1) return new TreeNode(pre[0]);
TreeNode root = new TreeNode(pre[0]);
int temp = 0;
for(int i = 0; i < in.length;i++)
{
if(in[i] == root.val)
{
temp = i;
break;
}
}
int[] P = Arrays.copyOfRange(pre,1,temp+1);
int[] I = Arrays.copyOfRange(in,0,temp);
root.left = buildTree(P,I);
P = Arrays.copyOfRange(pre,temp+1,pre.length);
I = Arrays.copyOfRange(in,temp+1,in.length);
root.right = buildTree(P,I);
return root;
}
}
听说有STACK的做法。。
得用MAP来对应 inOrder里INDEX和VAL的位置。
二刷
preOrder的第一个肯定是ROOT,然后从inOrder找这个ROOT的val,然后找到位置的左边就是LEFT,右边是RIGHT。 对应preOrder从第二个开始同样长度是左边,剩下的是右边。。
一刷是新建了Array作为新的pre/in order数组,很占空间,这次尝试记录他们的起始和结束坐标位置。
做起来费了点事。。
一开始犯了个错误,在inOrder中寻找ROOT的时候,从index = 1开始找,是不对的,应该从index = 0。
比如inOrder [4,7,6]
preOrder [4,6,7]
ROOT是4,在inOrder里index = 0就是了。。
public class Solution {
public TreeNode buildTree(int[] preorder, int[] inorder) {
return divide(preorder, inorder, 0, preorder.length - 1, 0, preorder.length - 1);
}
public TreeNode divide(int[] pre, int[] in,
int preL, int preR, int inL, int inR) {
if (preR < preL) return null;
if (preR == preL) return new TreeNode(pre[preL]);
TreeNode res = new TreeNode(pre[preL]);
int i = 0;
while (in[inL + i] != pre[preL]) i ++;
res.left = divide(pre, in, preL + 1, preL + i, inL, inL + i - 1);
res.right = divide(pre, in, preL + i + 1, preR, inL + i + 1, inR);
return res;
}
}
一般树的都可以迭代和递归,刚才是递归。
迭代我思考了一下,确实不会。。。。。。。