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

力扣题目链接(opens new window)

将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树。

本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。

示例:

思路

本题还是考察的构建二叉树

之前也有做过类似的题目,基本上来说,构造二叉树就是按照题目规则找根节点,然后调用递归不断构造出其左右子树即可

那么,本题的规则是什么?

题目要求我们将升序排列的有序数组,转换为一棵高度平衡二叉搜索树

因此,可以用数组的中间值为根节点来构造二叉搜索树

如果之后再来复习,肯定会想:如果中间值有两个怎么办

那现在先举个例子说明一下:

[1,2,3,4,5,6]

这里如果取中间值会有两个数,分别是3和4

实际上这不影响我们去构造一颗高度平衡二叉搜索树,因为不论选3还是4作为根节点,其左或右子树多出的一个节点也不会破坏高度的平衡

在这里,我们默认取左边的值(后面会说明原因)

确定了根节点之后,还是像之前的构建二叉树的题目,通过递归不断分割左右区间,进而构建出根节点的左右子树

代码

分析

使用递归法

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

不要一写参数就下意识的填根节点,这里都还没有找出根节点呢

因为要通过分割数组来构建二叉树,所以输入参数中肯定有数组nums,以及用于分割的左右区间

并且,我们需要返回的是一颗二叉树,那么返回值显然就是该树的根节点了

TreeNode* traversal(vector<int> nums, int left, int right){

}

2、确定终止条件

同理,不要一写终止条件就下意识的root==NULL

这里的终止条件应该与左右边界有关

即当 left > right 时应该结束

TreeNode* traversal(vector<int> nums, int left, int right){
//确定终止条件
if(left > right) return NULL; }

3、确定单层处理逻辑

现在要开始取数组的中间值并分割数组

TreeNode* traversal(vector<int> nums, int left, int right){
//确定终止条件
if(left > right) return NULL; //确定单层处理逻辑
//取中间值
int mid = (right - left)/2 + left;
}

为什么这样取中间值?

因为如果直接(right + left) / 2,当right、left均为int下的最大值,会导致数据溢出

上述方法可以避免这种问题,详见

TreeNode* traversal(vector<int> nums, int left, int right){
//确定终止条件
if(left > right) return NULL; //确定单层处理逻辑
//取中间值
int mid = (right - left)/2 + left;
//创建根节点
TreeNode* root = new TreeNode(nums[mid]);
//调用递归继续构建左右子树
root->left = traversal(nums, left, mid - 1);//跳过mid
root->right = traversal(nums, mid + 1, right);
return root;
}

注意,在分割数组时要跳过mid处的值

完整代码
class Solution {
public:
//确定递归函数的参数与返回值
TreeNode* traversal(vector<int>& nums, int left, int right){
//确定终止条件
if(left > right) return NULL;
//确定单层处理逻辑
//先找到数组里的中间值
int mid =(right - left) / 2 + left;//防止数据溢出
//初始化根节点
TreeNode* root = new TreeNode(nums[mid]);
//递归处理分割后数组的左区间和右区间
//注意要跳过mid
root->left = traversal(nums, left, mid - 1);
root->right = traversal(nums, mid + 1, right);
return root;
}
TreeNode* sortedArrayToBST(vector<int>& nums) {
return traversal(nums, 0 , nums.size() - 1);
}
};
构造二叉树的注意事项
1、找根节点

一般来说,没有特殊规定就找中间值作为根节点

本题中要求构建的二叉树为高度平衡的二叉搜索树,正好选中间值可以满足条件

2、根本原理

总结一下这几题构造二叉树的套路,无外乎:找根节点、递归分割数组构建左右子树

值得注意的是,在本题中,我们没有对nums本身进行操作,而是利用其下标进行的分割

而在之前做的几题里,我们分割数组时使用了**新建数组的方式

【LeetCode二叉树#19】有序数组转换为二叉搜索树(构造二叉树)的更多相关文章

  1. LeetCode:将有序数组转换为二叉搜索树【108】

    LeetCode:将有序数组转换为二叉搜索树[108] 题目描述 将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树. 本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差 ...

  2. LeetCode 108. 将有序数组转换为二叉搜索树(Convert Sorted Array to Binary Search Tree) 14

    108. 将有序数组转换为二叉搜索树 108. Convert Sorted Array to Binary Search Tree 题目描述 将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索 ...

  3. Java实现 LeetCode 108 将有序数组转换为二叉搜索树

    108. 将有序数组转换为二叉搜索树 将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树. 本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1. 示例: ...

  4. [LeetCode] 108. 将有序数组转换为二叉搜索树

    题目链接 : https://leetcode-cn.com/problems/convert-sorted-array-to-binary-search-tree/ 题目描述: 将一个按照升序排列的 ...

  5. 代码随想录算法训练营day23 | leetcode 669. 修剪二叉搜索树 ● 108.将有序数组转换为二叉搜索树 ● 538.把二叉搜索树转换为累加树

    LeetCode 669. 修剪二叉搜索树 分析1.0 递归遍历树时删除符合条件(不在区间中)的节点-如何遍历如何删除 如果当前节点大于范围,递归左树,反之右树 当前节点不在范围内,删除它,把它的子树 ...

  6. [leetcode-108,109] 将有序数组转换为二叉搜索树

    109. 有序链表转换二叉搜索树 Given a singly linked list where elements are sorted in ascending order, convert it ...

  7. LeetCode(108):将有序数组转换为二叉搜索树

    Easy! 题目描述: 将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树. 本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1. 示例: 给定有序数组 ...

  8. [LeetCode]105. 从前序与中序遍历序列构造二叉树(递归)、108. 将有序数组转换为二叉搜索树(递归、二分)

    题目 05. 从前序与中序遍历序列构造二叉树 根据一棵树的前序遍历与中序遍历构造二叉树. 注意: 你可以假设树中没有重复的元素. 题解 使用HashMap记录当前子树根节点在中序遍历中的位置,方便每次 ...

  9. LeetCode刷题笔记-递归-将有序数组转换为二叉搜索树

    题目描述 将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树. 本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1. 示例: 给定有序数组: [-10, ...

  10. LeetCode【108. 将有序数组转换为二叉搜索树】

    又是二叉树,最开始都忘记了二叉搜索树是什么意思,搜索了一下: 二叉搜索树:左节点都小于右节点,在这里就可以考虑将数组中的中间值作为根节点 平衡二叉树:就是左右节点高度不大于1 树就可以想到递归与迭代, ...

随机推荐

  1. [转帖]spec2017 安装和使用

    https://zhuanlan.zhihu.com/p/534205632 SPEC成立于1988年,SPEC基准广泛用于评估计算机系统的性能.SPEC CPU套件通过测量几个程序(例如编译器GCC ...

  2. [转帖]07-rsync企业真实项目备份案例实战(需求收集--服务器配置---客户端配置---报警机制---数据校验---邮件告警)

    https://developer.aliyun.com/article/885820?spm=a2c6h.24874632.expert-profile.279.7c46cfe9h5DxWK 简介: ...

  3. [转帖]总结:Servlet

    一.背景 开发了很久的web服务,使用了很多web框架,都忘记web技术最原始的模样了,今天来回顾下. 二.Servlet是什么? Servlet是sun公司提供的一门用于开发动态web资源的技术.我 ...

  4. Redis-rdb-tools与rdr工具学习与使用

    Redis-rdb-tools与rdr工具学习与使用 简要说明 rdb工具是python写的一套工具,可以分析dump文件,获取key等信息. rdb其实有一套rdb-profiler工具, 能够导出 ...

  5. Sqlite管理工具

    ! https://zhuanlan.zhihu.com/p/375188242 SQLiteStudio 开源免费的一款sqlite数据库管理软件,支持windows,linux,macos 官网: ...

  6. springboot security 权限控制 -- @PreAuthorize 的使用

    1. 说明 security 鉴权方式常用的有两种配置,1.配置文件中配置:2.使用注解标注:他们都是基于 acess 表达式,如果需要自定义逻辑的鉴权认证,只需要自定义 access 表达式即可.本 ...

  7. 从嘉手札<2024-1-17>

    昨天我以为 人生是一场体验 是一辆不会回头的列车 我们遇到了风景 感悟了风景 放下了风景 构成了自己 今天我以为 静水流深.光而不耀 可多思必多疑 思维是一种极为复杂的东西 我曾经觉得知行合一是对自我 ...

  8. Firefox浏览器的一些配置

    一.在新标签页打开书签 1.打开Firefox浏览器,地址栏输入about:config. 2.选择"接受风险并继续". 3.搜索browser.tabs.loadBookmark ...

  9. 《ASP.NET Core 与 RESTful API 开发实战》-- (第8章)-- 读书笔记(下)

    第 8 章 认证和安全 8.3 HTTPS HTTP 协议能够在客户端和服务器之间传递信息,特点是以明文的方式发送内容,并不提供任何方式的数据加密 为了解决 HTTP 协议这一缺陷,需要使用另一种协议 ...

  10. typora beta版本 typora免费版 typora 0.11.18 下载

    壹 ❀ 引 typora从1.0.0正式版开始就不再免费了,可能有一些开了自动检测更新的同学,在某次打开typora就看到了购买以及试用天数的弹窗,但typora正式之前的beta版依旧免费,这里就分 ...