根據(jù)一棵樹的前序遍歷與中序遍歷構(gòu)造二叉樹。
注意:
你可以假設(shè)樹中沒有重復(fù)的元素。
例如,給出
前序遍歷 preorder = [3,9,20,15,7]
中序遍歷 inorder = [9,3,15,20,7]
返回如下的二叉樹:
3
/
9 20
/
15 7
本題是一道比較復(fù)雜的題目,如果你沒有做過的話。
如果是不是代碼的實(shí)現(xiàn),本題也是比較簡(jiǎn)單的,我們通過前序知道了根節(jié)點(diǎn)是3,然后去中序遍歷看,在3前面的就是左子樹,在3后面的就是右子樹,然后繼續(xù)看前序遍歷,9是第一個(gè)節(jié)點(diǎn)就是左子樹的第一個(gè)節(jié)點(diǎn),20是右子樹的第一個(gè)節(jié)點(diǎn),然后又繼續(xù)中序遍歷,可以發(fā)現(xiàn)15是20的左子樹,7是20的右子樹,那本題就解決了。
那如何將上面的思考過程轉(zhuǎn)化為代碼呢?
這其實(shí)并不算太難,就是有點(diǎn)復(fù)雜,我們需要規(guī)劃一下流程,那就是我們每次創(chuàng)建節(jié)點(diǎn),都是通過前序遍歷來創(chuàng)建的節(jié)點(diǎn),我們確定左右子樹是通過中序遍歷的。
我們可以先從前序遍歷中找到本輪我們需要的節(jié)點(diǎn),然后去中序遍歷里,找到中序遍歷里的這個(gè)節(jié)點(diǎn),在這個(gè)節(jié)點(diǎn)之前的就是左子樹,在這個(gè)節(jié)點(diǎn)之后的就是右子樹。
因此代碼如下:
/**
* 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) {
if (preorder.length == 0 || inorder.length == 0)
return null;
return build(preorder,0,preorder.length-1,inorder,0,inorder.length-1);
}
TreeNode build(int[] preorder,int preStart,int preEnd,int[] inorder,int inStart,int inEnd){
TreeNode root = new TreeNode(preorder[preStart]);
root.left = null;
root.right = null;
int inRoot = inStart;
while (inRoot<=inEnd && inorder[inRoot] != preorder[preStart]) inRoot++;
int leftlen = inRoot-inStart;
int rightlen = inEnd - inRoot;
if (leftlen != 0)
root.left = build(preorder,preStart+1,preStart+leftlen,inorder,inStart,leftlen+inStart-1);
if (rightlen != 0)
root.right = build(preorder,preStart+leftlen+1,preStart+leftlen+rightlen,inorder,inRoot+1,inEnd);
return root;
}
}
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal
著作權(quán)歸領(lǐng)扣網(wǎng)絡(luò)所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系官方授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。