leetcode-105- 從前序與中序遍歷序列構造二叉樹(construct binary tree from preorder and inorder traversal)-java
阿新 • • 發佈:2018-11-19
題目及測試
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,呼叫建立節點的函式