【LeetCode】108. 将有序数组转换为二叉搜索树(简单)——代码随想录算法训练营Day23

题目链接:108. 将有序数组转换为二叉搜索树

题目描述

给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡 二叉搜索树。

高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。

示例 1:

输入:nums = [-10,-3,0,5,9]
输出:[0,-3,9,-10,null,5]
解释:[0,-10,5,null,-3,null,9] 也将被视为正确答案:

示例 2:

输入:nums = [1,3]
输出:[3,1]
解释:[1,null,3] 和 [3,1] 都是高度平衡二叉搜索树。

提示:

  • 1 <= nums.length <= 104
  • -104 <= nums[i] <= 104
  • nums 按 严格递增 顺序排列

文章讲解:代码随想录

视频讲解:构造平衡二叉搜索树!| LeetCode:108.将有序数组转换为二叉搜索树_哔哩哔哩_bilibili

题解1:递归法

思路:以数组中心元素为根节点,以左右两部分元素分别递归的构造左子树和右子树。

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {number[]} nums
 * @return {TreeNode}
 */
var sortedArrayToBST = function(nums) {
    // 左闭右开
    const build = function (left, right) {
        if (left === right) {
            return null;
        }
        const index = left + ((right - left - 1) >> 1); // 取区间中心元素为根节点
        return new TreeNode(nums[index], build(left, index), build(index + 1, right)); // 递归的构造左右子树,并返回根节点
    }
    return build(0, nums.length);
};

分析:时间复杂度为 O(n),空间复杂度为 O(logn)。

题解2:迭代法

思路:用3个栈(或队列)模拟分割数组的过程,1个队列存储节点,另外2个队列分别存储左下标和右下标。

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {number[]} nums
 * @return {TreeNode}
 */
var sortedArrayToBST = function(nums) {
    const nodeQue = [new TreeNode(0)]; // 创建节点栈
    const leftQue = [0]; // 初始化左区间栈,初始区间左边界为0
    const rightQue = [nums.length]; // 初始化右区间栈,左闭右开区间,初始区间右边界为 nums.length
    const root = new TreeNode(0); // 创建根节点
    nodeQue.push(root);
    while (nodeQue.length > 0) {
        const node = nodeQue.pop();
        const left = leftQue.pop();
        const right = rightQue.pop();
        const index = left + ((right - left - 1) >> 1);
        node.val = nums[index]; // 为当前节点赋值
        if (index > left) {
            // 创建左孩子,并入栈
            node.left = new TreeNode(0);
            nodeQue.push(node.left);
            // 创建区间 [left, index)
            leftQue.push(left);
            rightQue.push(index);
        }
        if (index + 1 < right) {
            // 创建右孩子,并入栈
            node.right = new TreeNode(0);
            nodeQue.push(node.right);
            // 创建区间 [index + 1, right)
            leftQue.push(index + 1);
            rightQue.push(right);
        }
    }
    return root;
};

分析:时间复杂度为 O(n),空间复杂度为 O(logn)。

收获

又是一道数组构造二叉树的题目,区间定义很重要,一定要统一。

  • 7
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

晴雪月乔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值