【LeetCode二叉树#19】有序数组转换为二叉搜索树(构造二叉树)
将有序数组转换为二叉搜索树
将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树。
本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 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】有序数组转换为二叉搜索树(构造二叉树)的更多相关文章
- LeetCode:将有序数组转换为二叉搜索树【108】
LeetCode:将有序数组转换为二叉搜索树[108] 题目描述 将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树. 本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差 ...
- LeetCode 108. 将有序数组转换为二叉搜索树(Convert Sorted Array to Binary Search Tree) 14
108. 将有序数组转换为二叉搜索树 108. Convert Sorted Array to Binary Search Tree 题目描述 将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索 ...
- Java实现 LeetCode 108 将有序数组转换为二叉搜索树
108. 将有序数组转换为二叉搜索树 将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树. 本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1. 示例: ...
- [LeetCode] 108. 将有序数组转换为二叉搜索树
题目链接 : https://leetcode-cn.com/problems/convert-sorted-array-to-binary-search-tree/ 题目描述: 将一个按照升序排列的 ...
- 代码随想录算法训练营day23 | leetcode 669. 修剪二叉搜索树 ● 108.将有序数组转换为二叉搜索树 ● 538.把二叉搜索树转换为累加树
LeetCode 669. 修剪二叉搜索树 分析1.0 递归遍历树时删除符合条件(不在区间中)的节点-如何遍历如何删除 如果当前节点大于范围,递归左树,反之右树 当前节点不在范围内,删除它,把它的子树 ...
- [leetcode-108,109] 将有序数组转换为二叉搜索树
109. 有序链表转换二叉搜索树 Given a singly linked list where elements are sorted in ascending order, convert it ...
- LeetCode(108):将有序数组转换为二叉搜索树
Easy! 题目描述: 将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树. 本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1. 示例: 给定有序数组 ...
- [LeetCode]105. 从前序与中序遍历序列构造二叉树(递归)、108. 将有序数组转换为二叉搜索树(递归、二分)
题目 05. 从前序与中序遍历序列构造二叉树 根据一棵树的前序遍历与中序遍历构造二叉树. 注意: 你可以假设树中没有重复的元素. 题解 使用HashMap记录当前子树根节点在中序遍历中的位置,方便每次 ...
- LeetCode刷题笔记-递归-将有序数组转换为二叉搜索树
题目描述 将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树. 本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1. 示例: 给定有序数组: [-10, ...
- LeetCode【108. 将有序数组转换为二叉搜索树】
又是二叉树,最开始都忘记了二叉搜索树是什么意思,搜索了一下: 二叉搜索树:左节点都小于右节点,在这里就可以考虑将数组中的中间值作为根节点 平衡二叉树:就是左右节点高度不大于1 树就可以想到递归与迭代, ...
随机推荐
- 谈JVM参数GC线程数ParallelGCThreads合理性设置
作者:京东零售 刘乐 导读:本篇文章聚焦JVM参数GC线程数的合理配置,从ParallelGCThreads参数含义.参数设置,到参数实验以及修改意见进行解析. 1. ParallelGCThread ...
- AsNoTracking()非跟踪数据 查询
刚开始学习使用EF ,做项目时需要查询数据将数据显示在datagrid中,使用如下方法: query是IQueryable的 在一次看别人写的代码的时候,发现了AsNoTracking()这个方法,并 ...
- TienChin 活动管理-设置活动的默认状态
// 设置活动未过期,相当于新增的活动,默认都是未过期的 activity.setActivityStatus(1);
- 设计模式学习-使用go实现中介者模式
中介模式 定义 优点 缺点 适用范围 代码实现 参考 中介模式 定义 中介模式(Mediator):用一个中介对象来封装一系列的对象交互.中介者使个各对象不需要显示的相互引用,从而使其藕合松散,而且可 ...
- 爱了爱了!推荐一个Github 70k+点赞的Java学习指南!
大家好,我是 Guide 哥!今天给大家推荐一个非常不错的 Java 教程类开源项目-JavaGuide ,Github 地址: https://github.com/Snailclimb/JavaG ...
- Paddlenlp之UIE关系抽取模型【高管关系抽取为例】
往期项目回顾: Paddlenlp之UIE模型实战实体抽取任务[打车数据.快递单] Paddlenlp之UIE分类模型[以情感倾向分析新闻分类为例]含智能标注方案) 应用实践:分类模型大集成者[Pad ...
- C/C++ 实现FTP文件上传下载
FTP(文件传输协议)是一种用于在网络上传输文件的标准协议.它属于因特网标准化的协议族之一,为文件的上传.下载和文件管理提供了一种标准化的方法,在Windows系统中操作FTP上传下载可以使用WinI ...
- 在k8s中,有哪些存储?
在 Kubernetes(简称 K8s)中,有多种内置和外部的存储解决方案,它们可以满足不同场景下的持久化存储需求.以下是一些常见的存储类型: PersistentVolume (PV): Persi ...
- 目录:CH57x/CH58x/CH59x/CH32V208低功耗蓝牙应用
外设相关: CH59x 系统16位PWM使用 - 小舟从此逝_1 - 博客园 (cnblogs.com) CH59X/CH58X/CH57X PWM使用 - 小舟从此逝_1 - 博客园 (cnblog ...
- 深入浅出Java多线程(九):synchronized与锁
引言 大家好,我是你们的老伙计秀才!今天带来的是[深入浅出Java多线程]系列的第九篇内容:synchronized与锁.大家觉得有用请点赞,喜欢请关注!秀才在此谢过大家了!!! 在现代软件开发中,多 ...