Leecode 105 Construct Binary Tree from Preorder and Inorder Traversal 根据前序、中序遍历构建二叉树

虽然算法不难,但是改进方案还是蛮多的,不太容易理解理解。

题目:

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

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

For example, given

preorder = [3,9,20,15,7]
inorder = [9,3,15,20,7]

Return the following binary tree:

    3
   / \
  9  20
    /  \
   15   7

第一种解决办法:32ms

package test;
//32ms
public class LC105Try1
{
	public TreeNode buildTree(int[] preorder, int[] inorder)
	{
		if (preorder.length == 0)
		{
			return null;
		}
		TreeNode ret=getPass(preorder,inorder,0,preorder.length-1,0,inorder.length-1);
		return ret;

	}
	public TreeNode getPass(int[] preorder, int[] inorder,int s1,int e1,int s2,int e2){
		//注意防止越界
		if(s1>e1){
			return null;
		}
		if(s1==e1){
			TreeNode node = new TreeNode(preorder[s1]);
			return node;
		}else{
			int val=preorder[s1];
			TreeNode root = new TreeNode(val);
			int i=s2;
			for( ;i<=e2;i++){
				if(inorder[i]==val){
					break;
				}
			}
			int leftlen=i-s2;
			
			root.left=getPass(preorder,inorder,s1+1,s1+leftlen,s2,i-1);
			root.right=getPass(preorder,inorder,s1+leftlen+1,e1,i+1,e2);
			return root;
		}
		
		
	}

}

第二种解决办法:3ms

package test;

import java.util.HashMap;
import java.util.Map;
//3ms
public class LC105Try2
{
	public TreeNode buildTree(int[] preorder, int[] inorder) {
	     Map<Integer, Integer> inorderHash = new HashMap<Integer, Integer>();
	    for (int i = 0; i < inorder.length; i++) { 
	        inorderHash.put(inorder[i], i);
	    }
	    return helper(0, 0, inorder.length - 1, preorder, inorderHash);
	}

	public TreeNode helper(int preStart, int inStart, int inEnd, int[] preorder, Map<Integer, Integer> inorderHash) {
	    
	    if (preStart > preorder.length - 1 || inStart > inEnd) {
	        return null;
	    }
	    TreeNode root = new TreeNode(preorder[preStart]);
	    int inIndex = inorderHash.get(root.val);
	    
	    root.left = helper(preStart + 1, inStart, inIndex - 1, preorder, inorderHash);
	    root.right = helper(preStart + inIndex - inStart + 1, inIndex + 1, inEnd, preorder, inorderHash);
	    return root;
	}    

}

第三种解决办法:1ms 最难理解

package test;

public class LC105Try3
{
	int inIndex = 0;//用的很巧妙
    int preIndex = 0;//很得精髓
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        return buildTree(preorder, inorder, null);
        
    }
    
    public TreeNode buildTree(int[] preorder, int[] inorder, TreeNode parent)
    {
        if(inIndex == inorder.length || parent != null && parent.val == inorder[inIndex])
            return null;
        
        TreeNode root = new TreeNode(preorder[preIndex++]);
        root.left = buildTree(preorder, inorder, root);
        inIndex++;
        root.right = buildTree(preorder, inorder, parent);
        return root;
    }

}

 

public TreeNode buildTree(int[] preorder, int[] inorder) {
        if(preorder.length==0){
            return null;
        }
        int tag=0;
        for(int i=0;i<inorder.length;i++){
            if(preorder[0]==inorder[i]){
                tag=i;
                break;
            }
        }
        TreeNode root=new TreeNode(preorder[0]);
        if(tag>0){
            int[] leftInorder = new int[tag];
            int[] leftPreorder = new int[tag];
            for(int i=0;i<tag;i++){
                leftInorder[i]=inorder[i];
                leftPreorder[i]=preorder[i+1];
            }   
            root.left=buildTree(leftPreorder,leftInorder);
        }
        if(inorder.length-tag-1>0){
            int[] rightInorder = new int[inorder.length-tag-1];
            int[] rightPreorder = new int[inorder.length-tag-1];

            for(int i=0;i<inorder.length-tag-1;i++){
                rightInorder[i]=inorder[tag+i+1];
                rightPreorder[i]=preorder[tag+i+1];
            }   
            root.right=buildTree(rightPreorder,rightInorder);
        }
        return root;

    }

哈哈

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值