1. 程式人生 > >leetcode-105- 從前序與中序遍歷序列構造二叉樹(construct binary tree from preorder and inorder traversal)-java

leetcode-105- 從前序與中序遍歷序列構造二叉樹(construct binary tree from preorder and inorder traversal)-java

題目及測試

package pid105;


/*從前序與中序遍歷序列構造二叉樹

根據一棵樹的前序遍歷與中序遍歷構造二叉樹。

注意:
你可以假設樹中沒有重複的元素。

例如,給出

前序遍歷 preorder = [3,9,20,15,7]
中序遍歷 inorder = [9,3,15,20,7]

返回如下的二叉樹:

    3
   / \
  9  20
    /  \
   15   7





}*/
public class main {
	
	public static void main(String[] args) {
		int[] ito=new int[]{3,9,20,15,7};
		int[] ito2=new int[]{9,3,15,20,7};
		//Object[] x=new Object[]{3,9,20,null,null,15,7};	
		//BinaryTree tree=new BinaryTree(x);
		//tree.printTree(tree.root);
		test(ito,ito2);
		
		
	}
		 
	private static void test(int[] ito,int[] ito2) {
		Solution solution = new Solution();
		TreeNode rtn;
		for(int now:ito){
			System.out.print(now+" ");
		}
		System.out.println();
		for(int now:ito2){
			System.out.print(now+" ");
		}
		System.out.println();
		long begin = System.currentTimeMillis();
		rtn = solution.buildTree(ito,ito2);//執行程式
		long end = System.currentTimeMillis();		
		System.out.println("rtn=" );
		new BinaryTree(1).printTree(rtn);
		System.out.println();
		System.out.println("耗時:" + (end - begin) + "ms");
		System.out.println("-------------------");
	}

}

解法1(成功,34ms,很慢)

從前序遍歷可以得到該段的root,從中序遍歷找到root,root的左右是root的左右節點,就可以按這個方法遞迴出這個節點的左右子節點

 

package pid105;

import java.util.LinkedList;
import java.util.List;

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
	public TreeNode buildTree(int[] preorder, int[] inorder) {
	    int length=preorder.length;
	    if(length==0){
	    	return null;
	    }
	    int mid=preorder[0];
	    int position=0;
	    int preFirst=0;
	    int preLast=0;
	    int inFirst=0;
	    int inLast=0;	
	    int leftSize=0;
	    int rightSize=0;
	    for(int i=0;i<inorder.length;i++){
	    	if(mid==inorder[i]){
	    		position=i;
	    		break;
	    	}
	    }
	    leftSize=position-0;
	    rightSize=length-position;
	    
	    TreeNode root=new TreeNode(mid);
	    //處理左邊
	    preFirst=1;
	    preLast=0+leftSize;
	    inFirst=0;
	    inLast=position-1;
	    root.left=buildTreeNode(preorder,preFirst,preLast,inorder,inFirst,inLast);
	    //處理右邊
	    preFirst=0+leftSize+1;
	    preLast=length-1;
	    inFirst=position+1;
	    inLast=length-1;	    
	    root.right=buildTreeNode(preorder,preFirst,preLast,inorder,inFirst,inLast);
		return root;
    }
	
	public TreeNode buildTreeNode(int[] preorder,int preFirst,int preLast,
			int[] inorder,int inFirst,int inLast) {
	    int length=preorder.length;
	    if(preLast<preFirst||inLast<inFirst||
	    		preLast>=length||inLast>=length||preFirst>=length||inFirst>=length||
	    		preLast<0||inLast<0||preFirst<0||inFirst<0){
	    	return null;
	    }
	    int mid=preorder[preFirst];
	    int position=0;
	    int preFirst2=0;
	    int preLast2=0;
	    int inFirst2=0;
	    int inLast2=0;	
	    int leftSize=0;
	    int rightSize=0;
	    for(int i=inFirst;i<inLast+1;i++){
	    	if(mid==inorder[i]){
	    		position=i;
	    		break;
	    	}
	    }
	    leftSize=position-inFirst;
	    rightSize=inLast-position;
	    TreeNode root=new TreeNode(mid);
	    //處理左邊
	    preFirst2=preFirst+1;
	    preLast2=preFirst+leftSize;
	    inFirst2=inFirst;
	    inLast2=position-1;	   
	    root.left=buildTreeNode(preorder,preFirst2,preLast2,inorder,inFirst2,inLast2);
	    //處理右邊
	    preFirst2=preFirst+leftSize+1;
	    preLast2=preLast;
	    inFirst2=position+1;
	    inLast2=inLast;
	    root.right=buildTreeNode(preorder,preFirst2,preLast2,inorder,inFirst2,inLast2);
	    return root;
    }
}

其餘做法類似,但是一般不寫兩個函式

要麼把左右的分為新的陣列,要麼直接用0,length-1,呼叫建立節點的函式