力扣第108题-将有序数组转换为二叉搜索树

151 阅读3分钟

「这是我参与11月更文挑战的第27天,活动详情查看:2021最后一次更文挑战

前言

力扣第108题 将有序数组转换为二叉搜索树 如下所示:

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

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

示例 1:

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

一、思路

题目比较短,我们可以先梳理一下题目中的关键信息

  • 输入:升序的一维数组(无重复元素)
  • 输出:高度平衡的二叉搜索数

二叉搜索树是指:左子树的值都小于根节点,右子树的值都大于根节点(如果左右子树不为空) 高度平衡二叉搜索树:指左右子树高度差不超过 1

示例1 中的升序数组 nums = [-10,-3,0,5,9] 来说的话,它可以组成的二叉搜索树有很多种。如下就是一种可能:

image.png

但是对于节点 0 来说,它的左子树的深度为 2,而右子树的深度为 0,差值超过了 1(对于根节点来说,左右子树的高度差也会超过 1 )。则这个二叉搜索树构不成一个高度平衡二叉搜索树

那如果保证左右子树的高度差不会超过 1 呢?

其实很简单,我们只需要使用二分法,取数组中间位置的元素作为根节点。再将根节点靠左的节点作为左子树,根节点靠右的节点作为右子树即可。

综上所述,递归的大致步骤分为以下三步:

left = 0,right = n

  1. mid = (left+right)/2,并将 nums[mid] 设为根节点
  2. 0 ~ mid -1 看作左子树
  3. mid ~ right 看作右子树

注意:递归中我们要正确的设置边界情况。在这里就是当 left > right 时,说明数组中没有元素可以用了,直接返回空节点 null 即可。

二、实现

实现代码

实现代码与思路中保持一致,使用递归会让代码看起来更简洁一点。

    /**
     * 高度平衡二叉树
     */
    public TreeNode sortedArrayToBST(int[] nums) {
        return dfs(nums, 0, nums.length-1);
    }

    public TreeNode dfs(int[] nums, int left, int right){
        if (left > right)
            return null;
        int mid = (left+right)/2;  // 取中间值
        TreeNode root = new TreeNode(nums[mid]);
        root.left = dfs(nums, left, mid-1);
        root.right = dfs(nums, mid+1, right);
        return root;
    }

测试代码

    public static void main(String[] args) {
        int[] nums = {-10,-3,0,5,9};
        TreeNode treeNode = new Number108().sortedArrayToBST(nums);
        System.out.println("debug");
    }

结果

image.png

三、总结

感谢看到最后,非常荣幸能够帮助到你~♥

如果你觉得我写的还不错的话,不妨给我点个赞吧!如有疑问,也可评论区见~