手把手带你刷二叉树(第二期)

上篇文章 手把手教你刷二叉树(第一篇) 连刷了三道二叉树题目,很多读者直呼内行。其实二叉树相关的算法真的不难,本文再来三道,手把手带你看看树的算法到底怎么做。

先来复习一下,我们说过写树的算法,关键思路如下:

把题目的要求细化,搞清楚根节点应该做什么,然后剩下的事情抛给前/中/后序的遍历框架就行了,我们千万不要跳进递归的细节里,你的脑袋才能压几个栈呀。

也许你还不太理解这句话,我们下面来看例子。

构造最大二叉树

先来道简单的,这是力扣第 654 题,题目如下:

deb795b7a1e9656ec27d580d00682857.png

函数签名如下:

TreeNode constructMaximumBinaryTree(int[] nums);

按照我们刚才说的,先明确根节点做什么?对于构造二叉树的问题,根节点要做的就是把想办法把自己构造出来

我们肯定要遍历数组把找到最大值 maxVal,把根节点 root 做出来,然后对 maxVal 左边的数组和右边的数组进行递归调用,作为 root 的左右子树。

按照题目给出的例子,输入的数组为 [3,2,1,6,0,5],对于整棵树的根节点来说,其实在做这件事:

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) {    if (nums is empty) return null;    // 找到数组中的最大值    int maxVal = Integer.MIN_VALUE;    int index = 0;    for (int i = 0; i < nums.length; i++) {        if (nums[i] > maxVal) {            maxVal = nums[i];            index = i;        }    }    TreeNode root = new TreeNode(maxVal);    // 递归调用构造左右子树    root.left = constructMaximumBinaryTree(nums[0..index-1]);    root.right = constructMaximumBinaryTree(nums[index+1..nums.length-1]);    return root;}

看懂了吗?对于每个根节点,只需要找到当前 nums 中的最大值和对应的索引,然后递归调用左右数组构造左右子树即可

明确了思路,我们可以重新写一个辅助函数 build,来控制 nums 的索引:

/* 主函数 */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;}

至此,这道题就做完了,还是挺简单的对吧,下面看两道更困难的常见算法题:让你用前序/中序遍历结果还原二叉树,以及用后序/中序遍历结果还原二叉树。


猜你喜欢

转载自blog.51cto.com/15064450/2570995
今日推荐