js算法题解(第二十四天)---108. 将有序数组转换为二叉搜索树

192 阅读3分钟

「这是我参与2022首次更文挑战的第27天,活动详情查看:2022首次更文挑战

前言

每天至少一道算法题,手撕算法

题目

这是leetcode上的第108道题目108. 将有序数组转换为二叉搜索树

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

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

图片.png

示例 1:

输入:nums = [-10,-3,0,5,9] 输出:[0,-3,9,-10,null,5] 解释:[0,-10,5,null,-3,null,9]

思路

第一步从题目中提取关键字

每个节点的左右两个子树的高度差的绝对值不超过 1 ,这不就是高度平衡二叉树么

我们先来了解一下什么是高度差的绝对值不超过1

先看奇数个数字的数组,我们直接上图看一下

      0
     / \
   -3   9
   /   /
 -10  5

0这个节点的左右子树的高度分别是多少呢?左子树高度为2,右子树的高度为2,所以他们的左右子树的差值为0,满足题目

我们再来看一个偶数个数字的数组

      -3
     / \
   -10   0
          \
           5

-3节点左子树的高度为1,-3节点右子树的高度为2,那么他们的高度差值是多少,是1

看上面的图,像不像把中间的数字提起来,他是以有序数组的中间元素为根节点,生成的二叉树

需要注意的是奇数和偶数之分

  • 奇数的话,那么直接取中间的数字提起来
  • 偶数的话,取中间左侧的数字和取中间右侧的数字都一样,两侧的子树差值都不会大于1

才开始我们要处理边界问题,还有就是返回root节点

var sortedArrayToBST = function(nums) {
    // 处理边界问题
    if(!nums.length){
        return null;
    }
    const buildBST = function(){
    
    }
    // 返回根节点
    const root = buildBST();
    return root;
};

现在我们就取中间的数字作为根节点的val值

var sortedArrayToBST = function(nums) {
    // 处理边界问题
    if(!nums.length){
        return null;
    }
    const buildBST=function(low,high){
        // 递归要写结束条件
        if(low>high){
            return null;
        }
        // 因为奇数,偶数的关系,所以center有可能是小数,那么如果是小数的话,我们选择左边的
        let center = Math.floor(low+(high-low)/2);
       
    }
    const root = buildBST(0,nums.length-1);
    return root;
};

然后建立node节点,并赋值左子树和右子树的根节点,方法同上,所以也肯定用递归

var sortedArrayToBST = function(nums) {
    // 处理边界问题
    if(!nums.length){
        return null;
    }
    const buildBST=function(low,high){
        // 递归要写结束条件
        if(low>high){
            return null;
        }
        // 因为奇数,偶数的关系,所以center有可能是小数,那么如果是小数的话,我们选择左边的
        let center = Math.floor(low+(high-low)/2);
        const node = new TreeNode(nums[center]);
        node.left = buildBST(low,center-1);
        node.right = buildBST(center+1,high);
        
        return node;
    }
    const root = buildBST(0,nums.length-1);
    return root;
};

题解

var sortedArrayToBST = function(nums) {
    // 处理边界问题
    if(!nums.length){
        return null;
    }
    const buildBST=function(low,high){
        // 递归要写结束条件
        if(low>high){
            return null;
        }
        // 因为奇数,偶数的关系,所以center有可能是小数,那么如果是小数的话,我们选择左边的
        let center = Math.floor(low+(high-low)/2);
        const node = new TreeNode(nums[center]);
        node.left = buildBST(low,center-1);
        node.right = buildBST(center+1,high);
        
        return node;
    }
    const root = buildBST(0,nums.length-1);
    return root;
};
  • 时间复杂度:O(n),n为nums的长度,每一个数会遍历一次,所以是O(n)
  • 空间复杂度:O(logn),递归就会把函数放到栈中,栈的最大深度也就是左子树或者右子树的最大深度,因为我们做的题目是平衡二叉树,高度差的绝对值不会超过1,所以栈的深度为O(logn)

参考

108. 将有序数组转换为二叉搜索树