劍指Offer面試題6 & Leetcode105
阿新 • • 發佈:2019-02-18
劍指Offer面試題6 & Leetcode105
Construct Binary Tree from Preorder and Inorder Traversal
重建二叉樹
Given preorder and inorder traversal of a tree, construct the binary tree.
解題思路
考慮:前序遍歷的第一個元素即為根節點的值,然後在中序遍歷中找到該元素,則位於其前的為左子樹的中序遍歷,位於其後的為右子樹的中序遍歷。同理,前序遍歷中第一個元素後先是左子樹的前序遍歷,然後是右子樹的前序遍歷。根據這個特點,用遞迴的方法實現二叉樹的重建。
注意這道題,如果想減小執行時間,在遞迴過程中儘量傳遞原陣列中各子樹遍歷的序號,而不是構建新的陣列進行傳遞。下面兩種解法,一種為傳遞陣列,一種為傳遞序號,均AC但時間不同。
Solution1 時間較長
public TreeNode buildTree(int[] preorder, int[] inorder) {
if(preorder.length == 0 && inorder.length == 0)
return null;
TreeNode root = new TreeNode(preorder[0 ]);
int flag = -1;
for(int i=0;i<inorder.length;i++){
if(inorder[i] == root.val){
flag = i;
break;
}
}
int[] newInorderLeft = new int[flag];
int[] newPreorderLeft = new int[flag];
int[] newInorderRight = new int[inorder.length-flag-1];
int[] newPreorderRight = new int[preorder.length-flag-1];
for(int i=0;i<flag;i++){
newInorderLeft[i] = inorder[i];
}
for(int i=0;i<flag;i++){
newPreorderLeft[i] = preorder[i+1];
}
for(int i=0;i<inorder.length-flag-1;i++){
newInorderRight[i] = inorder[flag+1+i];
}
for(int i=0;i<inorder.length-flag-1;i++){
newPreorderRight[i] = preorder[flag+1+i];
}
root.left = buildTree(newPreorderLeft,newInorderLeft);
root.right = buildTree(newPreorderRight, newInorderRight);
return root;
}
Solution2 時間較短
public TreeNode buildTree(int[] preorder, int[] inorder) {
if (preorder.length == 0 && inorder.length == 0)
return null;
return helper(0, 0, inorder.length - 1, preorder, inorder);
}
public TreeNode helper(int preStart, int inStart,
int inEnd, int[] preorder, int[] inorder) {
if (preStart >= preorder.length || inStart > inEnd)
return null;
TreeNode root = new TreeNode(preorder[preStart]);
int flag = -1;
for (int i = inStart; i <= inEnd; i++) {
if (inorder[i] == root.val) {
flag = i;
break;
}
}
root.left = helper(preStart + 1, inStart, flag - 1, preorder, inorder);
//注意對於右子樹的前序遍歷,開始的序號要減去其中序遍歷開始的序號,防止溢位, 即 flag + 1 - inStart 為右子樹針對此時的根節點的位移量。
root.right = helper(preStart + flag + 1 - inStart, flag + 1, inEnd, preorder, inorder);
return root;
}