力扣第108题 将有序数组转二叉搜索树 c++

题目

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

简单

相关标签

二叉搜索树 数组 分治 二叉树

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

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

示例 1:

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

示例 2:

复制代码
输入:nums = [1,3]
输出:[3,1]
解释:[1,null,3] 和 [3,1] 都是高度平衡二叉搜索树。

提示:

  • 1 <= nums.length <= 104
  • -104 <= nums[i] <= 104
  • nums严格递增 顺序排列

思路和解题方法

将有序数组转换为平衡二叉搜索树(BST)的功能。

  • traversal 函数是辅助函数,用于构建平衡BST。
    • 如果左指针 left 大于右指针 right,说明已经没有元素可以构建节点了,返回空指针。
    • 计算数组中间元素的索引 mid
    • 创建根节点,并赋值为数组中间元素的值。
    • 递归构建左子树,范围为 [left, mid-1]
    • 递归构建右子树,范围为 [mid+1, right]
    • 返回根节点。
  • sortedArrayToBST 函数是主函数,用于调用辅助函数将有序数组转换为平衡BST。
    • 调用辅助函数 traversal,传入数组和范围 [0, nums.size() - 1]
    • 返回根节点。

通过不断递归地构建左右子树,最终得到平衡的BST。

复杂度

时间复杂度:

O(n)

时间复杂度:O(n),其中 n 是数组的长度。每个数字只访问一次。

空间复杂度

O(log n)

空间复杂度:O(log⁡n),其中 n 是数组的长度。空间复杂度不考虑返回值,因此空间复杂度主要取决于递归栈的深度,递归栈的深度是 O(log⁡n)。

c++ 代码

cpp 复制代码
class Solution {
public:
    // 辅助函数,用于将有序数组转换为平衡二叉搜索树
    TreeNode* traversal(vector<int>& nums, int left, int right)
    {
        // 左指针大于右指针,说明已经没有元素可以构建节点了,返回空指针
        if(left > right) return NULL;
        
        // 计算数组中间元素的索引
        int mid = left + ((right - left) / 2);
        
        // 创建根节点,并赋值为数组中间元素的值
        TreeNode* root = new TreeNode(nums[mid]);
        
        // 递归构建左子树,范围为[left, mid-1]
        root->left = traversal(nums, left, mid - 1);
        
        // 递归构建右子树,范围为[mid+1, right]
        root->right = traversal(nums, mid + 1, right);
        
        // 返回根节点
        return root;
    }
    
    // 主函数,将有序数组转换为平衡二叉搜索树
    TreeNode* sortedArrayToBST(vector<int>& nums) {
        // 调用辅助函数,传入数组和范围[0, nums.size() - 1]
        TreeNode* root = traversal(nums, 0, nums.size() - 1);
        
        // 返回根节点
        return root;
    }
};

下附 迭代法版本代码

cpp 复制代码
class Solution {
public:
    TreeNode* sortedArrayToBST(vector<int>& nums) {
        if (nums.size() == 0) return nullptr;

        TreeNode* root = new TreeNode(0);   // 初始根节点
        queue<TreeNode*> nodeQue;           // 放遍历的节点
        queue<int> leftQue;                 // 保存左区间下标
        queue<int> rightQue;                // 保存右区间下标
        nodeQue.push(root);                 // 根节点入队列
        leftQue.push(0);                    // 0为左区间下标初始位置
        rightQue.push(nums.size() - 1);     // nums.size() - 1为右区间下标初始位置

        while (!nodeQue.empty()) {
            TreeNode* curNode = nodeQue.front();
            nodeQue.pop();
            int left = leftQue.front(); leftQue.pop();
            int right = rightQue.front(); rightQue.pop();
            int mid = left + ((right - left) / 2);

            curNode->val = nums[mid];       // 将mid对应的元素给中间节点

            if (left <= mid - 1) {          // 处理左区间
                curNode->left = new TreeNode(0);
                nodeQue.push(curNode->left);
                leftQue.push(left);
                rightQue.push(mid - 1);
            }

            if (right >= mid + 1) {         // 处理右区间
                curNode->right = new TreeNode(0);
                nodeQue.push(curNode->right);
                leftQue.push(mid + 1);
                rightQue.push(right);
            }
        }
        return root;
    }
};

觉得有用的话可以点点赞,支持一下。

如果愿意的话关注一下。会对你有更多的帮助。

每天都会不定时更新哦 >人< 。

相关推荐
ChoSeitaku6 分钟前
链表循环及差集相关算法题|判断循环双链表是否对称|两循环单链表合并成循环链表|使双向循环链表有序|单循环链表改双向循环链表|两链表的差集(C)
c语言·算法·链表
娅娅梨8 分钟前
C++ 错题本--not found for architecture x86_64 问题
开发语言·c++
DdddJMs__13512 分钟前
C语言 | Leetcode C语言题解之第557题反转字符串中的单词III
c语言·leetcode·题解
兵哥工控13 分钟前
MFC工控项目实例二十九主对话框调用子对话框设定参数值
c++·mfc
Fuxiao___15 分钟前
不使用递归的决策树生成算法
算法
我爱工作&工作love我20 分钟前
1435:【例题3】曲线 一本通 代替三分
c++·算法
娃娃丢没有坏心思1 小时前
C++20 概念与约束(2)—— 初识概念与约束
c语言·c++·现代c++
lexusv8ls600h1 小时前
探索 C++20:C++ 的新纪元
c++·c++20
lexusv8ls600h1 小时前
C++20 中最优雅的那个小特性 - Ranges
c++·c++20
白-胖-子1 小时前
【蓝桥等考C++真题】蓝桥杯等级考试C++组第13级L13真题原题(含答案)-统计数字
开发语言·c++·算法·蓝桥杯·等考·13级