105. Construct Binary Tree from Preorder and Inorder Traversal

树的题,要记住,树的题一般都有递归做法。。

对于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;
        
    }
}

一般树的都可以迭代和递归,刚才是递归。

迭代我思考了一下,确实不会。。。。。。。

posted @ 2016-11-28 12:15  哇呀呀..生气啦~  阅读(170)  评论(0编辑  收藏  举报