摘要:代码实现构建二叉树节点对应的值就是后序遍历数组的最后一个元素在中序遍历数组中的索引左子树的节点个数递归构造左右子树
把题目的要求细化,搞清楚根节点应该做什么,然后剩下的事情抛给前/中/后序的遍历框架就行了,我们千万不要跳进递归的细节里,你的脑袋才能压几个栈呀。
分析:
1.根节点要做什么??
把自己构建出来。
2.具体做什么??
遍历数组把找到最大值 maxVal,把根节点 root 做出来,然后对 maxVal 左边的数组和右边的数组进行递归调用,作为 root 的左右子树。
解题思路:
TreeNode constructMaximumBinaryTree([3,2,1,6,0,5]) { // 找到数组中的最大值 TreeNode root = new TreeNode(6); // 递归调用构造左右子树 root.left = constructMaximumBinaryTree([3,2,1]); root.right = constructMaximumBinaryTree([0,5]); return root;}
解答:
/* 主函数 */TreeNode constructMaximumBinaryTree(int[] nums) { return build(nums, 0, nums.length - 1);}/* 将 nums[lo..hi] 构造成符合条件的树,返回根节点 */TreeNode build(int[] nums, int lo, int hi) { // base case if (lo > hi) { return null; } // 找到数组中的最大值和对应的索引 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); // 递归调用构造左右子树 root.left = build(nums, lo, index - 1); root.right = build(nums, index + 1, hi); return root;}
⭐️重点题型标注!
分析:
想办法确定根节点的值,把根节点做出来,然后递归构造左右子树即可。
如何找到根节点??
前序遍历的第一个值preorder[0]就是根节点的值,关键在于如何通过根节点的值,将preorder和postorder数组划分成两半,构造根节点的左右子树?
根据思路写出对应的代码为:
/* 主函数 */TreeNode buildTree(int[] preorder, int[] inorder) { return build(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1);}/* 若前序遍历数组为 preorder[preStart..preEnd], 后续遍历数组为 postorder[postStart..postEnd], 构造二叉树,返回该二叉树的根节点 */TreeNode build(int[] preorder, int preStart, int preEnd, int[] inorder, int inStart, int inEnd) { // root 节点对应的值就是前序遍历数组的第一个元素 int rootVal = preorder[preStart]; // rootVal 在中序遍历数组中的索引 int index = 0; for (int i = inStart; i <= inEnd; i++) { if (inorder[i] == rootVal) { index = i; break; } } TreeNode root = new TreeNode(rootVal); // 递归构造左右子树 root.left = build(preorder, ?, ?, inorder, ?, ?); root.right = build(preorder, ?, ?, inorder, ?, ?); return root;}
得到构造左右子树的代码:
解答:
/** * 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);}/* 若前序遍历数组为 preorder[preStart..preEnd], 后续遍历数组为 postorder[postStart..postEnd], 构造二叉树,返回该二叉树的根节点 */ TreeNode build(int[] preorder, int preStart, int preEnd, int[] inorder, int inStart, int inEnd) { if (preStart > preEnd) { return null; } // root 节点对应的值就是前序遍历数组的第一个元素 int rootVal = preorder[preStart]; // rootVal 在中序遍历数组中的索引 int index = 0; for (int i = inStart; i <= inEnd; i++) { if (inorder[i] == rootVal) { index = i; break; } } int leftSize = index - inStart; // 先构造出当前根节点 TreeNode root = new TreeNode(rootVal); // 递归构造左右子树 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;}}
分析:
有了上一题的基础,发现只要画图发现左右子树的起止点就可以了。
代码实现:
class Solution { public TreeNode buildTree(int[] inorder, int[] postorder) { return build(inorder,0,inorder.length-1, postorder,0,postorder.length-1); } /**构建二叉树 */ TreeNode build(int[] inorder, int inStart, int inEnd, int[] postorder, int postStart, int postEnd) { if (inStart > inEnd) { return null; } // root 节点对应的值就是后序遍历数组的最后一个元素 int rootVal = postorder[postEnd]; // rootVal 在中序遍历数组中的索引 int index = 0; for (int i = inStart; i <= inEnd; i++) { if (inorder[i] == rootVal) { index = i; break; } } // 左子树的节点个数 int leftSize = index - inStart; TreeNode root = new TreeNode(rootVal); // 递归构造左右子树 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;}}
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/123607.html
摘要:后面也写了几种常见的排序算法,并用快排求第大值,另外如果之前版的作者看到的话可以留言,我会标明文章引用。 之前实习笔试的时候刷题一直用的java,也参考某篇文章写过java版的二叉树常见算法,因为马上要转正面试了,这几天都在准备面试,就把之前的翻出来用javascript重新写了一遍,二叉树基本都是递归处理的,也比较简单,就当做热身。后面也写了几种常见的排序算法,并用快排求第K大值,另...
阅读 2029·2023-04-25 14:50
阅读 2910·2021-11-17 09:33
阅读 2613·2019-08-30 13:07
阅读 2840·2019-08-29 16:57
阅读 910·2019-08-29 15:26
阅读 3546·2019-08-29 13:08
阅读 1992·2019-08-29 12:32
阅读 3384·2019-08-26 13:57