題目描述:
輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。
例如輸入前序遍歷序列{1,2,4,7,3,5,6,8}和中序遍歷序列{4,7,2,1,5,3,8,6},則重建二叉樹並返回。
起初看到這題我真的無從下手,準確的說是無法寫代碼,因爲自己只做過這類的筆試題,比如之前數據結構考試和軟考,
但是我只停留在會做題和知道大概思想的層面,代碼實現真的不會,之後看了討論區牛客大佬的答案,不得不佩服666
這裏採用的是遞歸的思想,首先,拿題目中的例子看,前序遍歷第一個即1肯定是整個樹的根節點,由此.可以得出,在後序遍歷
的數組中,1之前是整個樹的左子樹.而1之後,爲整個樹的右子樹,然後接着找左子樹和右子樹的根節點,然後按照同樣的方式再分
左右樹,startPre+1到startPre+i就是1的左子樹的節點的個數,這一段相當於通過索引把元素傳到下一個遞歸中,而i-startIn+startPre-1
是計算右子樹元素在數組中開始的位置
/** * @param in 中序 * @param pre 先序遍歷 * */ public static TreeNode reConstructBinaryTree(int [] pre,int [] in) { return reConstructBinaryTree(pre,0,pre.length-1,in,0,in.length-1); } private static TreeNode reConstructBinaryTree(int[] pre,int startPre,int endPre,int[] in,int startIn,int endIn){ if(startPre>endPre||startIn>endIn) return null; TreeNode tree = new TreeNode(pre[startPre]); for (int i = startIn;i<endIn;i++){ if (in[i]==pre[startPre]){ //System.out.println("left= pre "+pre[startPre+1]+"-"+pre[startPre+i]+" -- in "+in[startIn]+"-"+in[i-1]); //System.out.println("right= pre "+pre[i-startIn+startPre+1]+"-"+pre[endPre]+" -- in "+in[i+1]+"-"+in[endIn]); tree.left = reConstructBinaryTree(pre,startPre+1,startPre+i,in,startIn,i-1); tree.right = reConstructBinaryTree(pre,i-startIn+startPre+1,endPre,in,i+1,endIn); break; } } return tree; } public static class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int x) { val = x; } }
看了之後深感自己太菜,溜了溜了