【牛客刷题-算法】NC11 将升序数组转化为平衡二叉搜索树

简介: 【牛客刷题-算法】NC11 将升序数组转化为平衡二叉搜索树

1.题目描述


描述

给定一个升序排序的数组,将其转化为平衡二叉搜索树(BST).


平衡二叉搜索树指树上每个节点 node 都满足左子树中所有节点的的值都小于 node 的值,右子树中所有节点的值都大于 node 的值,并且左右子树的节点数量之差不大于1


数据范围:100000 ≤ n ≤ 10000 100000≤n≤10000100000≤n≤10000,数组中每个值满足 ∣ v a l ∣ ≤ 5000 ∣val∣≤5000∣val∣≤5000

进阶:空间复杂度 O ( n ) O ( n ) O(n)O(n)O(n)O(n),时间复杂度 O ( n ) O ( n ) O(n)O(n)O(n)O(n)


例如当输入的升序数组为[ − 1 , 0 , 1 , 2 ] [-1,0,1,2][−1,0,1,2]时,转化后的平衡二叉搜索树(BST)可以为{ 1 , 0 , 2 , − 1 } \{1,0,2,-1\}{1,0,2,−1},如下图所示:



或为 { 0 , − 1 , 1 , # , # , # , 2 } \{0,-1,1,\#,\#,\#,2\}{0,−1,1,#,#,#,2} ,如下图所示:



返回任意一种即可。


2.算法设计思路


我们只需根据数组参数构建出一颗相应的二叉树并返回根结点即可。首先我们要注意到:输入的数组是升序的。


于是我们只要:


选择数组的中间元素作为根结点

以中间元素左边的剩余元素,构建出左子树

以中间元素右边的剩余元素,构建出右子树

便可以递归地构建出相应的平衡二叉树。


3.算法实现


注:这里并不是完整代码,而只是核心代码的模式


1)遇到的一些问题

在具体的实现时,还会碰到一些细节处理上的问题。例如:


当需要用两个数组元素来构建一颗子树时,并不能再划分为左子树、根结点、右子树三个部分

已给出的函数声明sortedArrayToBST(int* num, int numLen )的参数列表并不能满足我们递归的需求

还有一个愚蠢的bug卡了我好久,就是把e - f写成了f - e。


2)具体代码

/**
 * struct TreeNode {
 *  int val;
 *  struct TreeNode *left;
 *  struct TreeNode *right;
 * };
 */
/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param num int整型一维数组 
 * @param numLen int num数组长度
 * @return TreeNode类
 */
struct TreeNode* create(int* num, int f, int e){
    struct TreeNode* root = (struct TreeNode *)malloc(sizeof(struct TreeNode));
    if(e - f == 0){
        root->val = num[f];  
        root->left = NULL;
        root->right = NULL;
    }
    else if(e - f == 1){
        root->val = num[f];  
        root->left = NULL;
        root->right = create(num, e, e);
    }
    else {
        int mid = (f + e) / 2;
        root->val = num[mid];  //num[mid] = 9;
        root->left = create(num, f, mid-1);
        root->right = create(num, mid+1, e);
    }
    return root;
}
struct TreeNode* sortedArrayToBST(int* num, int numLen ) {
    // write code here
    struct TreeNode* root = NULL;
    if(numLen == 0){
        return NULL;
    }
    root = create(num, 0, numLen-1);
    return root;
}

4.运行结果


成功通过!

image.png

相关文章
|
1月前
|
算法
【❤️算法笔记❤️】-每日一刷-23、合并 K 个升序链表
【❤️算法笔记❤️】-每日一刷-23、合并 K 个升序链表
32 0
|
1月前
|
算法
Leetcode 初级算法 --- 数组篇
Leetcode 初级算法 --- 数组篇
38 0
|
3月前
|
算法 测试技术
【算法】二分算法——寻找旋转排序数组中的最小值
【算法】二分算法——寻找旋转排序数组中的最小值
|
3月前
|
算法
【算法】二分查找——在排序数组中查找元素的第一个和最后一个位置
【算法】二分查找——在排序数组中查找元素的第一个和最后一个位置
|
1月前
|
算法 程序员 索引
数据结构与算法学习七:栈、数组模拟栈、单链表模拟栈、栈应用实例 实现 综合计算器
栈的基本概念、应用场景以及如何使用数组和单链表模拟栈,并展示了如何利用栈和中缀表达式实现一个综合计算器。
33 1
数据结构与算法学习七:栈、数组模拟栈、单链表模拟栈、栈应用实例 实现 综合计算器
|
1月前
|
存储 算法 定位技术
数据结构与算法学习二、稀疏数组与队列,数组模拟队列,模拟环形队列
这篇文章主要介绍了稀疏数组和队列的概念、应用实例以及如何使用数组模拟队列和环形队列的实现方法。
23 0
数据结构与算法学习二、稀疏数组与队列,数组模拟队列,模拟环形队列
|
1月前
|
数据可视化 搜索推荐 Python
Leecode 刷题笔记之可视化六大排序算法:冒泡、快速、归并、插入、选择、桶排序
这篇文章是关于LeetCode刷题笔记,主要介绍了六大排序算法(冒泡、快速、归并、插入、选择、桶排序)的Python实现及其可视化过程。
14 0
|
2月前
|
存储 算法 C#
C#二叉搜索树算法
C#二叉搜索树算法
|
3月前
|
存储 算法 Java
深入算法基础二分查找数组
文章深入学习了二分查找算法的基础,通过实战例子详细解释了算法的逻辑流程,强调了确定合法搜索边界的重要性,并提供了Java语言的代码实现。
深入算法基础二分查找数组
|
3月前
|
算法
【Azure Developer】完成算法第4版书中,第一节基础编码中的数组函数 histogrm()
【Azure Developer】完成算法第4版书中,第一节基础编码中的数组函数 histogrm()
下一篇
无影云桌面