摘要:代碼實現(xiàn)構(gòu)建二叉樹節(jié)點對應(yīng)的值就是后序遍歷數(shù)組的最后一個元素在中序遍歷數(shù)組中的索引左子樹的節(jié)點個數(shù)遞歸構(gòu)造左右子樹
把題目的要求細化,搞清楚根節(jié)點應(yīng)該做什么,然后剩下的事情拋給前/中/后序的遍歷框架就行了,我們千萬不要跳進遞歸的細節(jié)里,你的腦袋才能壓幾個棧呀。
分析:
1.根節(jié)點要做什么??
把自己構(gòu)建出來。
2.具體做什么??
遍歷數(shù)組把找到最大值 maxVal,把根節(jié)點 root 做出來,然后對 maxVal 左邊的數(shù)組和右邊的數(shù)組進行遞歸調(diào)用,作為 root 的左右子樹。
解題思路:
TreeNode constructMaximumBinaryTree([3,2,1,6,0,5]) { // 找到數(shù)組中的最大值 TreeNode root = new TreeNode(6); // 遞歸調(diào)用構(gòu)造左右子樹 root.left = constructMaximumBinaryTree([3,2,1]); root.right = constructMaximumBinaryTree([0,5]); return root;}
解答:
/* 主函數(shù) */TreeNode constructMaximumBinaryTree(int[] nums) { return build(nums, 0, nums.length - 1);}/* 將 nums[lo..hi] 構(gòu)造成符合條件的樹,返回根節(jié)點 */TreeNode build(int[] nums, int lo, int hi) { // base case if (lo > hi) { return null; } // 找到數(shù)組中的最大值和對應(yīng)的索引 int index = -1, maxVal = Integer.MIN_VALUE; for (int i = lo; i <= hi; i++) { if (maxVal < nums[i]) { index = i; maxVal = nums[i]; } } TreeNode root = new TreeNode(maxVal); // 遞歸調(diào)用構(gòu)造左右子樹 root.left = build(nums, lo, index - 1); root.right = build(nums, index + 1, hi); return root;}
??重點題型標(biāo)注!
分析:
想辦法確定根節(jié)點的值,把根節(jié)點做出來,然后遞歸構(gòu)造左右子樹即可。
如何找到根節(jié)點??
前序遍歷的第一個值preorder[0]就是根節(jié)點的值,關(guān)鍵在于如何通過根節(jié)點的值,將preorder和postorder數(shù)組劃分成兩半,構(gòu)造根節(jié)點的左右子樹?
根據(jù)思路寫出對應(yīng)的代碼為:
/* 主函數(shù) */TreeNode buildTree(int[] preorder, int[] inorder) { return build(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1);}/* 若前序遍歷數(shù)組為 preorder[preStart..preEnd], 后續(xù)遍歷數(shù)組為 postorder[postStart..postEnd], 構(gòu)造二叉樹,返回該二叉樹的根節(jié)點 */TreeNode build(int[] preorder, int preStart, int preEnd, int[] inorder, int inStart, int inEnd) { // root 節(jié)點對應(yīng)的值就是前序遍歷數(shù)組的第一個元素 int rootVal = preorder[preStart]; // rootVal 在中序遍歷數(shù)組中的索引 int index = 0; for (int i = inStart; i <= inEnd; i++) { if (inorder[i] == rootVal) { index = i; break; } } TreeNode root = new TreeNode(rootVal); // 遞歸構(gòu)造左右子樹 root.left = build(preorder, ?, ?, inorder, ?, ?); root.right = build(preorder, ?, ?, inorder, ?, ?); return root;}
得到構(gòu)造左右子樹的代碼:
解答:
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode() {} * TreeNode(int val) { this.val = val; } * TreeNode(int val, TreeNode left, TreeNode right) { * this.val = val; * this.left = left; * this.right = right; * } * } */class Solution {TreeNode buildTree(int[] preorder, int[] inorder) { return build(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1);}/* 若前序遍歷數(shù)組為 preorder[preStart..preEnd], 后續(xù)遍歷數(shù)組為 postorder[postStart..postEnd], 構(gòu)造二叉樹,返回該二叉樹的根節(jié)點 */ TreeNode build(int[] preorder, int preStart, int preEnd, int[] inorder, int inStart, int inEnd) { if (preStart > preEnd) { return null; } // root 節(jié)點對應(yīng)的值就是前序遍歷數(shù)組的第一個元素 int rootVal = preorder[preStart]; // rootVal 在中序遍歷數(shù)組中的索引 int index = 0; for (int i = inStart; i <= inEnd; i++) { if (inorder[i] == rootVal) { index = i; break; } } int leftSize = index - inStart; // 先構(gòu)造出當(dāng)前根節(jié)點 TreeNode root = new TreeNode(rootVal); // 遞歸構(gòu)造左右子樹 root.left = build(preorder, preStart + 1, preStart + leftSize, inorder, inStart, index - 1); root.right = build(preorder, preStart + leftSize + 1, preEnd, inorder, index + 1, inEnd); return root;}}
分析:
有了上一題的基礎(chǔ),發(fā)現(xiàn)只要畫圖發(fā)現(xiàn)左右子樹的起止點就可以了。
代碼實現(xiàn):
class Solution { public TreeNode buildTree(int[] inorder, int[] postorder) { return build(inorder,0,inorder.length-1, postorder,0,postorder.length-1); } /**構(gòu)建二叉樹 */ TreeNode build(int[] inorder, int inStart, int inEnd, int[] postorder, int postStart, int postEnd) { if (inStart > inEnd) { return null; } // root 節(jié)點對應(yīng)的值就是后序遍歷數(shù)組的最后一個元素 int rootVal = postorder[postEnd]; // rootVal 在中序遍歷數(shù)組中的索引 int index = 0; for (int i = inStart; i <= inEnd; i++) { if (inorder[i] == rootVal) { index = i; break; } } // 左子樹的節(jié)點個數(shù) int leftSize = index - inStart; TreeNode root = new TreeNode(rootVal); // 遞歸構(gòu)造左右子樹 root.left = build(inorder, inStart, index - 1, postorder, postStart, postStart + leftSize - 1); root.right = build(inorder, index + 1, inEnd, postorder, postStart + leftSize, postEnd - 1); return root;}}
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/123607.html
摘要:后面也寫了幾種常見的排序算法,并用快排求第大值,另外如果之前版的作者看到的話可以留言,我會標(biāo)明文章引用。 之前實習(xí)筆試的時候刷題一直用的java,也參考某篇文章寫過java版的二叉樹常見算法,因為馬上要轉(zhuǎn)正面試了,這幾天都在準(zhǔn)備面試,就把之前的翻出來用javascript重新寫了一遍,二叉樹基本都是遞歸處理的,也比較簡單,就當(dāng)做熱身。后面也寫了幾種常見的排序算法,并用快排求第K大值,另...
閱讀 2035·2023-04-25 14:50
閱讀 2914·2021-11-17 09:33
閱讀 2618·2019-08-30 13:07
閱讀 2845·2019-08-29 16:57
閱讀 913·2019-08-29 15:26
閱讀 3555·2019-08-29 13:08
閱讀 1996·2019-08-29 12:32
閱讀 3391·2019-08-26 13:57