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