第108题


将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树。 本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。 示例: 给定有序数组: [-10,-3,0,5,9], 一个可能的答案是:[0,-3,9,-10,null,5],它可以表示下面这个高度平衡二叉搜索树: 0
/ \
-3 9
/ /
-10 5 来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/convert-sorted-array-to-binary-search-tree

解题思路

  • 从定义我们知道,BST的中序遍历为一个递增序列,给定的数组其实就是中序遍历结果
  • 取有序数组的中间值做根,左边部分做左树,右边部分做右树如此循环迭代去二分就可还原这棵BST树

代码实现

1.二分+递归实现

每次取数组的中间值,作为二分搜索树的中间节点,依次递归下去即可

//二分+递归实现
class Solution108_1 {
public TreeNode sortedArrayToBST(int[] nums) {
return convertToBST(nums, 0, nums.length - 1);
} TreeNode convertToBST(int[] nums, int begin, int end) {
if (begin > end) return null;
//取中值
int mid = begin + (end - begin) / 2;
TreeNode root = new TreeNode(nums[mid]);
//左叶子树
root.left = convertToBST(nums, begin, mid - 1);
//右叶子树
root.right = convertToBST(nums, mid + 1, end);
return root;
}
}

2.利用堆栈,去递归化实现

  • 定义一个栈,用来存将要处理数组的左索引和右索引值
  • 定义另一个栈,用来存树的节点,因为节点是先初始化,后更新节点值的迭代过程。所以需要借用堆栈先建好节点,建立好关系。
//非递归实现
class Solution108_2 {
public TreeNode sortedArrayToBST(int[] nums) {
if (nums == null || nums.length == 0) return null;
Stack<Integer> stack = new Stack<Integer>();
//数组最大索引值入栈
stack.add(nums.length - 1);
//数组最小索引值入栈
stack.add(0); Stack<TreeNode> tree = new Stack<TreeNode>();
TreeNode root = new TreeNode(0);
//随便new树节点入栈
tree.add(root); while (!stack.isEmpty()) {
int left = stack.pop();
int right = stack.pop();
//求出中间节点索引值
int mid = left + (right - left) / 2;
TreeNode node = tree.pop();
//更新根节点值
node.val = nums[mid]; //计算左叶子节点最大最小索引值
int r = mid - 1, l = left;
//如果存在左叶子节点
if (l <= r) {
node.left = new TreeNode(0);
//随便new个树节点入栈
tree.add(node.left); //对应右索引值入栈
stack.push(r);
//对应左索引值入栈
stack.push(l);
} //计算右节点最大最小索引值
l = mid + 1;
r = right;
if (l <= r) {
node.right = new TreeNode(0);
//随便new个树节点入栈
tree.add(node.right); //对应右索引值入栈
stack.push(r);
//对应左索引值入栈
stack.add(l);
}
}
return root;
}
}

总结

不出所料,通过提交代码发现堆栈实现会比递归执行效率慢很多,这是因为:

  • 堆栈实现需要频繁的push(入栈)、pop(出栈)操作导致性能下降

资料

LeetCode 将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树的更多相关文章

  1. convert sorted list to binary search tree(将有序链表转成平衡二叉搜索树)

    Given a singly linked list where elements are sorted in ascending order, convert it to a height bala ...

  2. 算法进阶面试题04——平衡二叉搜索树、AVL/红黑/SB树、删除和调整平衡的方法、输出大楼轮廓、累加和等于num的最长数组、滴滴Xor

    接着第三课的内容和讲了第四课的部分内容 1.介绍二叉搜索树 在二叉树上,何为一个节点的后继节点? 何为搜索二叉树? 如何实现搜索二叉树的查找?插入?删除? 二叉树的概念上衍生出的. 任何一个节点,左比 ...

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

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. 进程_Linux内核设计与实现笔记

    进程 进程是处于执行期的程序以及相关资源的总称,是正在执行的代码的实时结果. 进程部分位于Kernel的PM层.进程是Unix操作系统的抽象概念中最基本的一种,操作系统的存在就是为了运行用户程序,所以 ...

  2. 基于servlet+filter+反射模拟实现天猫首页的后端

    前言:为了深入web原理,本项目没有使用框架,主要描述了从请求到页面展现的思路,详情请见文末的具体项目 一.为什么要用filter?直接servlet实现不就行了 因为天猫这样的项目需要很多servl ...

  3. CSRF的原理与防御 | 你想不想来一次CSRF攻击?

    CSRF是Cross Site Request Forgery的缩写,中文翻译过来是跨站请求伪造.这个漏洞往往能给用户带来巨大的损失,CSRF在等保安全检测中,也是一个非常重要的检测项.但是在我们的网 ...

  4. TC297B - 外设头文件解析(以IO为例)

    打开例程,目录树下的Includes中包含了各个片上资源对应的头文件,这些头文件定义了相应外设的寄存器地址(寄存器是内置于各个 IP 外设中,是一种用于配置外设功能的存储器,就是一种内存,并且有相对应 ...

  5. MyCat学习 ------分库分表 随笔

    垂直切分.水平切分 1.垂直分库,解决库中表太多的问题. 2.垂直分表,解决表中列太多的问题.例如 商品表 包含 产地.二维码 .时间.价格.各个列.分为不同的小表. 水平切分, 大数据表拆分为小表 ...

  6. NSURLSession使用(整理版)

    NSURLSession使用 1.NSURLSession诞生于2013年,但其在前几年一直生活在NSURLConnection的阴影下,直到iOS9的出现,NSURLConnection被官方宣布弃 ...

  7. 开通博客第一天,记录此时此刻,开始学习加强c#

    从2017年6月毕业到现在,不断的学习.net,在工作中不断的加强技术,终于在此时此刻决定开通博客,记录此后每一天学习的技术点,两年来,每天所涉及的技术点很杂,学了这个忘了那个,总感觉在进步却总是觉得 ...

  8. Mybatis 报错 java.lang.IllegalArgumentException: Result Maps collection does not contain value for java.lang.Inte

    like ‘%java.lang.IllegalArgumentException: Result Maps collection does not contain value for java.la ...

  9. 5-- String 、StringBulid 、StringBuffer的区别

    String是典型的Immutable(不可变)类,被声明为final class,所有属性都是final的.由于它的不可变性,类似拼接.截取字符串等操作都会产生新的String对象,往往编码中常常对 ...

  10. Elasticsearch系列---搜索分页和deep paging问题

    概要 本篇从介绍搜索分页为起点,简单阐述分页式数据搜索与原有集中式数据搜索思维方式的差异,就分页问题对deep paging问题的现象进行分析,最后介绍分页式系统top N的案例. 搜索分页语法 El ...