劍指 Offer 07. 重建二叉樹
阿新 • • 發佈:2020-08-07
遞迴:
public TreeNode buildTree(int[] preorder, int[] inorder) { int len = preorder.length; if(len == 0) return null; TreeNode head = new TreeNode(preorder[0]); int index = 0; for(int i = 0;i<inorder.length;i++){ if(inorder[i] == preorder[0]){ index= i; break; } } head.left = buildTree(Arrays.copyOfRange(preorder,1,index+1), Arrays.copyOfRange(inorder,0,index)); head.right = buildTree(Arrays.copyOfRange(preorder,index+1,len), Arrays.copyOfRange(inorder,index+1,len));return head; }
public TreeNode buildTree(int[] preorder, int[] inorder) { int len = preorder.length; if(len == 0) return null; TreeNode head = new TreeNode(preorder[0]); int index = 0; for(int i = 0;i<inorder.length;i++){ if(inorder[i] == preorder[0]){ index= i; break; } } int[] pre_left = Arrays.copyOfRange(preorder,1,index+1); int[] in_left = Arrays.copyOfRange(inorder,0,index); int[] pre_right = Arrays.copyOfRange(preorder,index+1,len); int[] in_right = Arrays.copyOfRange(inorder,index+1,len); head.left = buildTree(pre_left, in_left); head.right = buildTree(pre_right, in_right); return head; }
只是拷貝了新陣列,記憶體消耗就減了一半。
但是效能還是不行啊,除了遞迴還能怎麼做?
用指標直接完成:
public TreeNode buildTree(int[] preorder, int[] inorder) { int len = preorder.length; if (len == 0) return null; return dfs(len,preorder,0,inorder,0); } // 從前序和中序構造二叉樹,前序和中序是大陣列中的一段[start, start + count) private TreeNode dfs(int count, int[] preOrder, int preStart, int[] inOrder, int inStart) { if (count <= 0) return null; int rootValue = preOrder[preStart]; TreeNode root = new TreeNode(rootValue); // 從inorder中找到root值,(inorder)左邊就是左子樹,(inorder)右邊就是右子樹 // 然後在preorder中,數出與inorder中相同的個數即可 int pos = inStart + count - 1; for (; pos >= inStart; --pos) { if (inOrder[pos] == rootValue) { break; } } int leftCount = pos - inStart; int rightCount = inStart + count - pos - 1; if (leftCount > 0) { int leftInStart = inStart; int leftPreStart = preStart + 1; root.left = dfs(leftCount, preOrder, leftPreStart, inOrder, leftInStart); } if (rightCount > 0) { int rightInStart = pos + 1; int rightPreStart = preStart + 1 + leftCount; root.right = dfs(rightCount, preOrder, rightPreStart, inOrder, rightInStart); } return root; }