zoukankan      html  css  js  c++  java
  • 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;
            
        }
    }
    

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

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

  • 相关阅读:
    多线程与线程池
    hdu1506 Largest Rectangle in a Histogram
    安装mathtype出问题卸载后 office2016打开mathtype弹错误窗口
    最小总代价 状压DP
    Sumsets 递推
    不容易系列之(4)——考新郎 递推
    超级楼梯 递推
    阿牛的EOF牛肉串(递推)
    子串查询(二维前缀数组) 2018"百度之星"程序设计大赛
    cf#513 B. Maximum Sum of Digits
  • 原文地址:https://www.cnblogs.com/reboot329/p/6108975.html
Copyright © 2011-2022 走看看