【算法20天:Day20】第六章二叉树 LeetCode 最大二叉树(654)

18 阅读2分钟

题目一:

image.png

解法一:(递归)

解题思路:这个题主要就是按照题目的要求进行即可,主要是要注意递归终止条件的判断。

构造树一般采用的是前序遍历,因为先构造中间节点,然后递归构造左子树和右子树。

  • 确定递归函数的参数和返回值

参数就是传入的是存放元素的数组,返回该数组构造的二叉树的头结点,返回类型是指向节点的指针。

var constructMaximumBinaryTree = function(nums) {}
  • 确定终止条件

题目中说了输入的数组大小一定是大于等于1的,所以我们不用考虑小于1的情况,那么当递归遍历的时候,如果传入的数组大小为1,说明遍历到了叶子节点了。

那么应该定义一个新的节点,并把这个数组的数值赋给新的节点,然后返回这个节点。 这表示一个数组大小是1的时候,构造了一个新的节点,并返回。

const node = new TreeNode(0)
if (nums.length === 1) {
    node.val = nums[0]
    return node
}
  • 确定单层递归的逻辑(三步)
  1. 先要找到数组中最大的值和对应的下标, 最大的值构造根节点,下标用来下一步分割数组。
let maxValue = 0
let maxValueIndex = 0
for (let i = 0; i < nums.length; i++) {
    if (nums[i] > maxValue) {
        maxValue = nums[i]
        maxValueIndex = i
    }
}
node.val = maxValue
  1. 最大值所在的下标左区间 构造左子树

这里要判断maxValueIndex > 0,因为要保证左区间至少有一个数值。

if (maxValueIndex > 0) {
    vector<int> newVec(nums.begin(), nums.begin() + maxValueIndex);
    node->left = constructMaximumBinaryTree(newVec);
}
  1. 最大值所在的下标右区间 构造右子树

判断maxValueIndex < (nums.size() - 1),确保右区间至少有一个数值。

var constructMaximumBinaryTree = function(nums) {
    const node = new TreeNode(0)
    if (nums.length === 1) {
        node.val = nums[0]
        return node
    }
    let maxValue = 0
    let maxValueIndex = 0
    for (let i = 0; i < nums.length; i++) {
        if (nums[i] > maxValue) {
            maxValue = nums[i]
            maxValueIndex = i
        }
    }
    node.val = maxValue
    if (maxValueIndex > 0) {
        node.left = constructMaximumBinaryTree(nums.slice(0, maxValueIndex))
    }
    if (maxValueIndex < nums.length - 1) {
        node.right = constructMaximumBinaryTree(nums.slice(maxValueIndex + 1))
    }
    return node
};

优化:

每次分隔不用定义新的数组,而是通过下标索引直接在原数组上操作。

一般情况来说:如果让空节点(空指针)进入递归,就不加if,如果不让空节点进入递归,就加if限制一下, 终止条件也会相应的调整。

var constructMaximumBinaryTree = function (nums) {
    const BuildTree = (arr, left, right) => {
        if (left > right)
            return null;
        let maxValue = -1;
        let maxIndex = -1;
        for (let i = left; i <= right; ++i) {
            if (arr[i] > maxValue) {
                maxValue = arr[i];
                maxIndex = i;
            }
        }
        let root = new TreeNode(maxValue);
        root.left = BuildTree(arr, left, maxIndex - 1);
        root.right = BuildTree(arr, maxIndex + 1, right);
        return root;
    }
    let root = BuildTree(nums, 0, nums.length - 1);
    return root;
};