LeetCode 算法:将有序数组转换为二叉搜索树 c++

原题链接🔗:将有序数组转换为二叉搜索树
难度:简单⭐️

题目

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

示例 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 按 严格递增 顺序排列

平衡二叉搜索树

  • 平衡二叉搜索树(Balanced Binary Search Tree,简称BBST)是一种特殊的二叉搜索树,它在保持二叉搜索树的所有性质的同时,还保证了树的高度尽可能地小。这通常通过在插入和删除操作后重新平衡树来实现,以确保树的任何两个子树的高度差不会超过1。

  • 平衡二叉搜索树的一个常见实现是AVL树,它是一种自平衡的二叉搜索树,其名称来源于其发明者Adelson-Velsky和Landis。AVL树在每次插入或删除操作后,都会进行必要的旋转操作来保持树的平衡。

  • AVL树的平衡操作包括四种基本的旋转:

    • 左旋(Left Rotation):当节点的右子树比左子树高时,进行左旋来减少树的高度。
    • 右旋(Right Rotation):当节点的左子树比右子树高时,进行右旋来减少树的高度。
    • 左右旋(Left-Right Rotation):当节点的左子树的右子树比左子树高时,首先对左子树进行右旋,然后对节点进行左旋。
    • 右左旋(Right-Left Rotation):当节点的右子树的左子树比右子树高时,首先对右子树进行左旋,然后对节点进行右旋。
  • AVL树的每个节点除了存储值和指向左右子节点的指针外,还存储了一个平衡因子(balance factor),通常是左子树高度和右子树高度的差值。节点的平衡因子只能是-1、0或1。

题解

递归法

  1. 解题思路

将一个有序数组转换为二叉搜索树(BST)的解题思路基于二叉搜索树的性质:左子树上所有节点的值 < 根节点的值 < 右子树上所有节点的值。对于一个有序数组,我们可以利用数组的有序性来快速确定根节点和左右子树的划分点。

以下是解题步骤:

  • 确定根节点:对于有序数组,中间元素(数组长度的一半)是一个很好的根节点候选,因为它可以很好地维持左右子树的大小平衡。

  • 递归构建左右子树:使用数组下标来划分,左子树包含从数组开始到根节点前的部分,右子树包含从根节点的下一个元素到数组末尾的部分。

  • 递归终止条件:当子数组为空时,返回null。

  • 构建树:对于每个子数组,重复上述步骤,递归地构建左右子树。

  • 返回根节点:递归结束时,返回构建的树的根节点。

下面是具体的算法逻辑:

  • 定义一个递归函数sortedArrayToBST,它接收有序数组的起始索引和结束索引作为参数。
  • 计算中间索引mid:mid = (start+ end) / 2
  • 使用mid索引处的值创建一个新的树节点。
  • 递归地调用sortedArrayToBST来构建左子树,使用start和mid - 1作为新的参数。
  • 递归地调用sortedArrayToBST来构建右子树,使用mid + 1和end作为新的参数。
  • 将左子树和右子树分别赋值给新创建的根节点的左右子节点。
  • 返回根节点。
  1. 复杂度:时间复杂度O(n),空间复杂度O(logn)。

  2. c++ demo

#include <iostream>
#include <vector>

// 定义二叉树节点
struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};

// 将有序数组转换为二叉搜索树的函数
class Solution {
public:
    TreeNode* sortedArrayToBST(std::vector<int>& nums) {
        return sortedArrayToBSTHelper(nums, 0, nums.size() - 1);
    }

private:
    TreeNode* sortedArrayToBSTHelper(std::vector<int>& nums, int start, int end) {
        if (start > end) {
            return nullptr;
        }
        // 选择中间的元素作为根节点
        int mid = start + (end - start) / 2;
        TreeNode* node = new TreeNode(nums[mid]);
        // 递归地构建左子树和右子树
        node->left = sortedArrayToBSTHelper(nums, start, mid - 1);
        node->right = sortedArrayToBSTHelper(nums, mid + 1, end);
        return node;
    }
};

// 辅助函数:中序遍历二叉树并打印节点值
void inorderTraversal(TreeNode* node) {
    if (!node) return;
    inorderTraversal(node->left);
    std::cout << node->val << " ";
    inorderTraversal(node->right);
}

// 辅助函数:释放二叉树内存
void deleteTree(TreeNode* node) {
    if (!node) return;
    deleteTree(node->left);
    deleteTree(node->right);
    delete node;
}

int main() {
    // 创建Solution实例
    Solution solution;
    // 有序数组
    std::vector<int> nums = { -10, -3, 0, 5, 9 };
    // 将有序数组转换为BST
    TreeNode* root = solution.sortedArrayToBST(nums);

    // 中序遍历BST并打印节点值
    std::cout << "Inorder traversal of the constructed BST:" << std::endl;
    inorderTraversal(root);
    std::cout << std::endl;

    // 释放二叉树内存
    deleteTree(root);

    return 0;
}
  • 输出结果:

Inorder traversal of the constructed BST:
-10 -3 0 5 9

  1. demo 仓库地址:sortedArrayToBST

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/743863.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

visual studio打包QT工程发布exe安装包

一、实验环境 软件版本下载链接visual studioMicrosoft Visual Studio Community 2022 (64 位) - Current 版本 17.7.5QTv6.6.3NSISv3.10官网 或 百度云1234Windows11 二、程序准备 1、程序生成 使用 visual studio 打开工程&#xff0c;选择 Release 模式后&#xff0c;点…

韩顺平0基础学java——第31天

p612-637 IO流 IO流原理及流的分类 Java lO流原理 1.I/O是Input/Output的缩弓&#xff0c;IV/O技术是非常实用的技术&#xff0c;用于处理数据传输。 如读/写文件&#xff0c;网络通讯等。 2. Java程序中&#xff0c;对于数据的输入/输出操作以”流(stream)”的方式进行。 3…

系统漏洞复现与勒索病毒

知识点&#xff1a;SMB漏洞介绍、漏洞复现流程、勒索病毒攻击与防护 渗透测试相关&#xff1a; 基本概念&#xff1a; 渗透测试就是利用我们所掌握的渗透知识&#xff0c;对网站进行一步一步的渗透&#xff0c;发现其中存在的漏洞和隐藏的风险&#xff0c;然后撰写一篇测试报…

Word如何在页眉中插入和删除横线

你平常是否遇见到Word的页眉中有一条横线&#xff0c;怎么也删不了&#xff01;&#xff01;&#xff01; 今天刘小生分享如何在页眉中插入和删除横线&#xff0c;我们一起操练起来吧&#xff01; 1、Word页眉插入横线 选择【插入】-【页眉页脚】&#xff0c;在“页眉页脚”…

基于SSM+VUE的网上订餐系统(带1w+文档)

基于SSMVUE的网上订餐系统(带1w文档) 网上订餐系统的数据库里面存储的各种动态信息&#xff0c;也为上层管理人员作出重大决策提供了大量的事实依据。总之&#xff0c;网上订餐系统是一款可以真正提升管理者的办公效率的软件系统。 项目简介 基于SSMVUE的网上订餐系统(带1w文档…

【LLM之KG】KoPA论文阅读笔记

研究背景 知识图谱补全&#xff08;KGC&#xff09;是通过预测知识图谱中缺失的三元组来完善知识图谱的信息。传统方法主要基于嵌入和预训练语言模型&#xff0c;但这些方法往往忽视了知识图谱的结构信息&#xff0c;导致预测效果不佳。 研究目标 本文的研究目标是探索如何将…

YOLOv8关键点pose训练自己的数据集

这里写自定义目录标题 YOLOv8关键点pose训练自己的数据集一、项目代码下载二、制作自己的关键点pose数据集2.1 标注(非常重要)2.1.1 标注软件2.1.2 标注注意事项a.多类别检测框b.单类别检测框2.2 格式转换(非常重要)2.3 数据集划分三、YOLOv8-pose训练关键点数据集3.1 训练…

小程序注册

【 一 】小程序注册 微信公众平台 https://mp.weixin.qq.com/ https://mp.weixin.qq.com/注册 邮箱激活 小程序账户注册 微信小程序配置 微信小程序开发流程 添加项目成员 【 二 】云服务 lass 基础设施服务&#xff08;组装机&#xff09; 你买了一大堆的电脑配件&#x…

Live Wallpaper Themes 4K Pro for Mac v19.9 超高清4K动态壁纸

Live Wallpaper & Themes 4K Pro for Mac v19.7 是一款专为Mac用户设计的超高清4K动态壁纸应用程序。它凭借出色的视觉效果和丰富的个性化设置&#xff0c;为用户带来全新的桌面体验。 这款软件提供了大量精美的动态壁纸供用户选择&#xff0c;涵盖了各种风格和主题&#…

STM32学习-HAL库 串口通信

学完标准库之后&#xff0c;本来想学习freertos的&#xff0c;但是看了很多教程都是移植的HAL库程序&#xff0c;这里再学习一些HAL库的内容&#xff0c;有了基础这里直接学习主要的外设。 HAL库对于串口主要有两个结构体UART_InitTypeDef和UART_HandleTypeDef&#xff0c;前者…

Java三层框架的解析

引言&#xff1a;欢迎各位点击收看本篇博客&#xff0c;在历经很多的艰辛&#xff0c;我也是成功由小白浅浅进入了入门行列&#xff0c;也是收货到很多的知识&#xff0c;每次看黑马的JavaWeb课程视频&#xff0c;才使一个小菜鸡见识到了Java前后端是如何进行交互访问的&#x…

亚马逊云科技官方活动:一个月拿下助理架构师SAA+云从业者考试认证(送半价折扣券)

为了帮助大家考取AWS SAA和AWS云从业者认证&#xff0c;小李哥争取到了大量考试半价50%折扣券&#xff0c;使用折扣券考试最多可省75刀(545元人民币)。 领取折扣券需要加入云师兄必过班群&#xff0c;在群中免费领取。目前必过班群招募到了超过200名小伙伴&#xff0c;名额有限…

杂记 | 搭建反向代理防止OpenAI API被封禁(对于此次收到邮件提示7月9日后将被屏蔽的解决参考)

文章目录 重要声明&#xff08;免责&#xff09;01 OpenAI封禁API的情况02 解决方案及原理2.1 原因分析2.2 解决方案2.3 步骤概述 03 操作步骤3.1 购买一个海外服务器3.2 申请一个域名3.3 将域名指向代理服务器3.4 在代理服务器上安装nginx3.5 配置反向代理 重要声明&#xff0…

如何利用小猪APP分发进行高效的APP封装打包

你有没有想过&#xff0c;为什么有些应用程序似乎在一夜之间就上线了&#xff0c;而你的应用却还在封装打包的过程中挣扎&#xff1f;别担心&#xff0c;这里有一个秘密武器&#xff0c;它叫做小猪APP分发。 小猪app封装www.ppzhu.net 什么是APP封装打包&#xff1f; APP封装…

从零开始做题:修猫

修猫 1 题目 2 解题 2.1 使用Stegslove分析图片 (base) ┌──(holyeyes㉿kali2023)-[~/Misc/tool-misc] └─$ java -jar Stegsolve.jar 2.2 analyse -frame browser 2.3 得到flag DASCTF{818ca3a840e768da7d5fcdeaedd5012f}

解决GPU 显存未能完全释放

一、 现象 算法同学反馈显存未能完全释放。 二、解决方法 一条命令搞定 注意&#xff1a;执行时注意不要误杀其他的python进程&#xff0c;需要确认好。 我的这条命令是将所有python进程都杀死了 ps -elf | grep python | awk {print $4} | xargs kill -s 9

Redis源码学习:SDS设计与内存管理

为什么Redis选择SDS 1、缓解C语言字符串的缺陷 在 C 语言中可以使用 char* 字符数组来实现字符串。每个字符串分配一段连续的内存空间&#xff0c;依次存放字符串中的每一个字符&#xff0c;最后以null字符结尾。这种设计存在以下问题&#xff1a; 1、低效的操作 每次获取字…

【containerd】Containerd高阶命令行工具nerdctl

前言 对于习惯了使用docker cli的用户来说&#xff0c;containerd的命令行工具ctr使用起来不是很顺手&#xff0c;此时别慌&#xff0c;还有另外一个命令行工具项目nerdctl可供我们选择。 nerdctl是一个与docker cli风格兼容的containerd的cli工具。 nerdctl已经作为子项目加入…

数据分析必备:一步步教你如何用matplotlib做数据可视化(12)

1、Matplotlib 3D线框图 线框图采用值网格并将其投影到指定的三维表面上&#xff0c;并且可以使得到的三维形式非常容易可视化。plot_wireframe()函数用于此目的 import matplotlib.pyplot as plt import numpy as np import math import seaborn as sns plt.rcParams[font.s…