Studying-代码随想录训练营day21| 669.修建二叉搜索树、108.将有序数组转换为二叉搜索树、538.把二叉搜索树转换为累加树、二叉树总结

news2024/12/27 12:04:42

第21天,二叉树最后一篇,冲💪

目录

669.修建二叉搜索树

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

538.把二叉搜索树转换为累加树

二叉树总结


669.修建二叉搜索树

文档讲解:代码随想录修建二叉搜索树

视频讲解:手撕修建二叉搜索树

题目:

学习:

本题需要注意的点很多,不能够轻易的就把节点删除,首先:1.本题给出的最小边界值和最大边界值,不一定会存在树中,只是提供一个区间大小,因此不能够节点判断是否等于low或者high。2.在找到小于low的值后不能够直接将其删除,因为它的右孩子不一定小于low,同理大于high的节点也不能直接删除,还需要关注它的左孩子。3.在2的基础上,也不能直接把右孩子返回,因为右孩子大于low的情况下,右孩子的左孩子还是可能会小于low需要删除,因此还需要不断的进行遍历。(该情况如下图所示,如果区间在[2,3]之间)

依据上述所说,来设计递归三部曲。

代码:

//时间复杂度O(n)
//空间复杂度O(n)
class Solution {
public:
    //确定返回值,本题需要重新构造二叉树节点,因此使用返回值更加方便,当然也可以没有返回值就需要手动进行左右孩子构造
    TreeNode* trimBST(TreeNode* root, int low, int high) {
        //确定终止条件
        if (root == nullptr) return nullptr;
        
        //确定单层递归逻辑(核心是将root转移到low和high区间内)
        //1.当前值大于high
        if (root->val > high) {
            //在该节点左边找寻是否有合适的值
            return trimBST(root->left, low, high);
        }
        //2.当前值小于low
        if (root->val < low) {
            //在该节点右边找寻是否有合适的值
            return trimBST(root->right, low, high);
        }
        //3.当前值在low和high区间内,但是还不能就此下定义,还需要判断该节点左右孩子是否合格
        root->left = trimBST(root->left, low, high);
        root->right = trimBST(root->right, low, high);
        //持续把修改后的节点返回上层
        return root;
    }
};

代码:本题也能够使用迭代法,且由于二叉搜索树自带遍历条件,因此不需要额外空间。

//时间复杂度O(n)
//空间复杂度O(1)
class Solution {
public:
    TreeNode* trimBST(TreeNode* root, int L, int R) {
        if (!root) return nullptr;

        // 处理头结点,让root移动到[L, R] 范围内,注意是左闭右闭
        while (root != nullptr && (root->val < L || root->val > R)) {
            if (root->val < L) root = root->right; // 小于L往右走
            else root = root->left; // 大于R往左走
        }
        TreeNode *cur = root;
        // 此时root已经在[L, R] 范围内,处理左孩子元素小于L的情况
        while (cur != nullptr) {
            while (cur->left && cur->left->val < L) {
                cur->left = cur->left->right;
            }
            cur = cur->left;
        }
        cur = root;

        // 此时root已经在[L, R] 范围内,处理右孩子大于R的情况
        while (cur != nullptr) {
            while (cur->right && cur->right->val > R) {
                cur->right = cur->right->left;
            }
            cur = cur->right;
        }
        return root;
    }
};

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

文档讲解:代码随想录将有序数组转换为二叉搜索树

视频讲解:手撕将有序数组转换为二叉搜索树

题目:

学习:

注意本题需要构造的不仅是二叉搜索树还需要是一颗平衡二叉树。平衡二叉树需要所有中间节点的左右孩子的高度差不大于1。

依据上述条件,又因为本题给的数组已经是一个升序排列的数组了,因此本题显然是从中间节点进行构造,每次取数组的中间节点,即可构造出平衡的二叉搜索树。注意如果数组是奇数,显然选中间的节点,如果数组是偶数则中间的两个节点选哪个都可以,只要统一就行,最后构造出的二叉树会有所区别,这也是本题答案不唯一的原因。

代码:

//时间复杂度O(n)
//空间复杂度O(n^2)
class Solution {
public:
    TreeNode* sortedArrayToBST(vector<int>& nums) {
        //确定终止条件
        if(nums.size() == 0) return nullptr;

        //取中间值
        int mid = nums.size()/2;
        TreeNode* node = new  TreeNode(nums[mid]);
        //左区间
        vector<int> left(nums.begin(), nums.begin() + mid);
        //右区间
        vector<int> right(nums.begin() + mid + 1, nums.end());
        //分配左右子树
        node->left = sortedArrayToBST(left);
        node->right = sortedArrayToBST(right);
        return node;
    }
};

代码:不使用额外空间,下标确定数组区间

//时间复杂度O(n)
//空间复杂度O(n)递归产生的栈空间
class Solution {
public:
    //不使用额外空间,下标法
    TreeNode* traversal(vector<int>& nums, int left, int right) {
        //确定终止条件(区间左闭右闭)
        if(left > right) return nullptr;
        //找到中间值
        int mid = left + (right - left)/2; //防止数值越界
        TreeNode* node = new TreeNode(nums[mid]);
        
        //左区间
        node->left = traversal(nums, left, mid - 1);
        //右区间
        node->right = traversal(nums, mid + 1, right);
        return node;
    }

    TreeNode* sortedArrayToBST(vector<int>& nums) {
        return traversal(nums, 0, nums.size() - 1);
    }
};

538.把二叉搜索树转换为累加树

文档讲解:代码随想录把二叉搜索树转换为累加树

视频讲解:手撕把二叉搜索树转换为累加树

题目:

学习:本题最重要的是需要找到它的规律,本题是将每个节点的新值转变为等于原树中大于或等于node.val的值之和。如果将二叉搜索树通过中序遍历转化为数组来看的话,其实就是从后往前依次累加。因此本题应该采用的遍历方法是反中序遍历,通过右中左的遍历顺序,因此将节点值累加。

注意本题累加过程中,采用的是双指针的方法,需要一个指向当前节点的前一个节点pre来保存上一个节点的累加和。

代码:

//时间复杂度O(n)
//空间复杂度O(n)
class Solution {
public:
    TreeNode* pre = nullptr; //指向当前节点的前一个节点
    //本题不需要返回值,只用将当前值改变就行
    void traversal(TreeNode* root) {
        //终止条件
        if(root == nullptr) return;

        //本题的遍历顺序应该为右中左
        //右
        traversal(root->right);
        //中
        if(pre != nullptr) {
            root->val = root->val + pre->val;
        }
        pre = root;
        //左
        traversal(root->left);
    }
    TreeNode* convertBST(TreeNode* root) {
        traversal(root);
        return root;
    }
};

代码:本题也能够使用迭代法进行

//时间复杂度O(n)
//空间复杂度O(n)
class Solution {
private:
    int pre; // 记录前一个节点的数值
    void traversal(TreeNode* root) {
        stack<TreeNode*> st;
        TreeNode* cur = root;
        while (cur != NULL || !st.empty()) {
            if (cur != NULL) {
                st.push(cur);
                cur = cur->right;   // 右
            } else {
                cur = st.top();     // 中
                st.pop();
                cur->val += pre;
                pre = cur->val;
                cur = cur->left;    // 左
            }
        }
    }
public:
    TreeNode* convertBST(TreeNode* root) {
        pre = 0;
        traversal(root);
        return root;
    }
};

二叉树总结

对于二叉树来说我们首先需要掌握的就是递归这一算法,确定递归三部曲掌握通过递归进行的二叉树的前序遍历、中序遍历、后序遍历的方法。

其次对于二叉树来说,它的迭代方法同样也很重要,递归由于其不断递归的特殊性,稍有不慎就容易导致栈溢出,且问题相对于迭代法不好排查。因此掌握迭代法对于实际工程使用也十分重要。

这七天我们对二叉树的遍历方式,各种属性,二叉树的修改和构造都进行了详细的练习。并且对二叉树中一个重要的类型二叉搜索树也进行了详细的考察,二叉搜索树自带的遍历顺序,能够便于解答很多问题,同时对二叉搜索树进行中序遍历能够得到一个非递减序列也是重要的性质之一。

总结来说:

  • 涉及到二叉树的构造,无论普通二叉树还是二叉搜索树一定都是先构造中节点。

  • 求普通二叉树的属性,一般是后序,一般要通过递归函数的返回值做计算。(包括是否对称,求最大深度,最小深度,有多少个节点,是否平衡,路径问题,左叶子之和、左下角的值等)

  • 求二叉搜索树的属性,一定是中序了,要不白瞎了有序性了。

 二叉树系列就这么完美结束了!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

力扣爆刷第155天之TOP100五连刷41-45(下一个排列、正序数组中位数、归并排序链表)

力扣爆刷第155天之TOP100五连刷41-45&#xff08;下一个排列、正序数组中位数、归并排序链表&#xff09; 文章目录 力扣爆刷第155天之TOP100五连刷41-45&#xff08;下一个排列、正序数组中位数、归并排序链表&#xff09;一、31. 下一个排列二、4. 寻找两个正序数组的中位数三…

Python基于逻辑回归分类模型、决策树分类模型、LightGBM分类模型和XGBoost分类模型实现车辆贷款违约预测项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 随着经济的发展和人民生活水平的提高&#xff0c;汽车消费在居民消费中所占比例逐渐增加&#xff0c;汽…

【Linux】CentOS7重置登录密码

一、具体步骤 1、启动虚拟机&#xff0c;进入下方页面时选择第一个选项&#xff0c;并按e 2、在下方界面 添加 init/bin/sh,刚开始进来可能看不到&#xff0c;需要按下键盘的↓键。 3、填写完成后ctrlx保存 4、输入mount -o remount, rw / 5、输入passwd 用户名;输入后出现…

澳汰尔(Altair® )FlowSimulator™ 集成热流体系统设计

FlowSimulator 是一款 3D 设计工具&#xff0c;可为 CAD 集成环境中的流体和热系统提供跨学科建模和优化。 系统级设计变得越来越重要&#xff0c;因为企业正在面临仿真复杂工作周期的挑战。需要采用 FlowSimulator 等快速软件解决方案对整个系统进行建模&#xff0c;包括对快…

VAE-pytorch代码

import osimport torch import torch.nn as nn import torch.nn.functional as F from torch.utils.data import DataLoaderfrom torchvision import transforms, datasets from torchvision.utils import save_imagefrom tqdm import tqdmclass VAE(nn.Module): # 定义VAE模型…

【AI大模型】Transformers大模型库(十四):Datasets Viewer

目录 一、引言 二、Datasets Viewer数据查看器 2.1 概述 2.2 示例 三、总结 一、引言 这里的Transformers指的是huggingface开发的大模型库&#xff0c;为huggingface上数以万计的预训练大模型提供预测、训练等服务。 &#x1f917; Transformers 提供了数以千计的预训练…

python-立方和不等式

[题目描述] 试求满足下述立方和不等式的 m 的整数解。 1^32^3...m^3≤n。本题算法如下&#xff1a; 对指定的 n&#xff0c;设置求和循环&#xff0c;从 i1 开始&#xff0c;i 递增1取值&#xff0c;把 i^3 (或 i∗i∗i)累加到 s&#xff0c;直至 s>n&#xff0c;脱离循环作…

VMware Workstation环境下,邮件(E-Mail)服务的安装配置,并用Windows7来验证测试

需求说明: 某企业信息中心计划使用IP地址17216.11.0用于虚拟网络测试,注册域名为xyz.net.cn.并将172.16.11.2作为主域名的服务器(DNS服务器)的IP地址,将172.16.11.3分配给虚拟网络测试的DHCP服务器,将172.16.11.4分配给虚拟网络测试的web服务器,将172.16.11.5分配给FTP服务器…

深度學習筆記14-CIFAR10彩色圖片識別(Pytorch)

&#x1f368; 本文為&#x1f517;365天深度學習訓練營 中的學習紀錄博客&#x1f356; 原作者&#xff1a;K同学啊 | 接輔導、項目定制 一、我的環境 電腦系統&#xff1a;Windows 10 顯卡&#xff1a;NVIDIA GeForce GTX 1060 6GB 語言環境&#xff1a;Python 3.7.0 開發…

ubuntu 18.04 server源码编译安装freeswitch 1.10.7支持音视频通话、收发短信——筑梦之路

软件版本说明 ubuntu版本18.04&#xff1a;https://releases.ubuntu.com/18.04.6/ubuntu-18.04.6-live-server-amd64.iso freeswitch 版本1.10.7&#xff1a;https://files.freeswitch.org/freeswitch-releases/freeswitch-1.10.7.-release.tar.gz spandsp包&#xff1a;https:…

家人们谁懂啊?手机信息删除找不回,原来3个技巧就能恢复

你是否也曾经遇到过这样的情况&#xff1a;手机里的重要信息不小心删除了&#xff0c;翻遍所有地方都找不到&#xff0c;心情烦躁到了极点。其实&#xff0c;信息删除后找回它们并不像你想象的那么复杂。不要担心&#xff0c;因为今天我将与你分享3个技巧&#xff0c;帮助你轻松…

1 哈希应用

O(1) 的哈希 Python中的哈希表主要通过内置的字典&#xff08;dict&#xff09;类型实现。对于字典的操作&#xff0c;包括插入&#xff08;insert&#xff09;、删除&#xff08;delete&#xff09;和查找&#xff08;lookup&#xff09;的时间复杂度&#xff0c;在理想情况下…

上位机图像处理和嵌入式模块部署(mcu之iap升级)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 mcu种类很多&#xff0c;如果是开发的时候需要对固件升级&#xff0c;整体还是比较容易的。不管是dap&#xff0c;还是st-link v2、j-link&#xf…

idea中使用springboot进行开发时遇到的工程结构问题汇总

idea中的工程结构和eclipse中不同&#xff0c;但是配置的内容都是一样的。 IDEA中也就是这个页面&#xff0c;快捷键ctrlaltshifts 如果在eclipse中&#xff0c;经常会遇到jre和jdk不正确的情况&#xff0c;但IDEA中这个问题很少&#xff0c;但是IDEA中会经常由于未正常配置根…

ESXI存储设备已经分区,无法创建数据存储。

问题:ESXi 存储设备已经分区完成&#xff0c;并且有 VMFS 文件系统&#xff0c;无法创建数据存储&#xff0c;选项是灰色。 解决办法&#xff1a;通过命令行工具 在现有的 VMFS 分区上创建数据存储。 在现有的 VMFS 分区上创建数据存储 1.ESXI开SSH2.windows自带CMD登入ESXI。&…

使用宝塔安装ModstartCMS (非一键安装)

操作系统 Linux Windows 推荐 Linux 操作系统&#xff0c;性能比较好 软件环境 稳定版 PHP 5.6 PHP 7.0 MySQL >5.0 PHP Extension&#xff1a;Fileinfo Apache/Nginx Laravel 9.0 版本 PHP 8.1 MySQL >5.0 PHP Extension&#xff1a;Fileinfo Apache/Ngin…

Windows 注册表是什么?如何备份注册表?

Windows注册表&#xff08;Windows Registry&#xff09;是微软Windows操作系统中的一个重要组件&#xff0c;用于存储系统和应用程序的配置信息和选项。下面就给大家详细讲解一下什么是注册表。 注册表的概念 Windows 注册表是一个集中管理的数据库&#xff0c;存储了系统、…

安霸CVFlow推理开发笔记

一、安霸环境搭建&#xff1a; 1.远程172.20.62.13 2. 打开Virtualbox&#xff0c;所在目录&#xff1a;E:\Program Files\Oracle\VirtualBox 3. 配置好ubuntu18.04环境&#xff0c;Ubuntu密码&#xff1a;amba 4. 安装toolchain&#xff0c;解压Ambarella_Toolchain_CNNGe…

成都工业学院2022级数据库原理及应用专周课程学生选课系统(基础篇)

运行环境 操作系统&#xff1a;Windows 11 家庭版 运行软件&#xff1a;Navicat Premium 16 项目内容 需求分析 学生&#xff1a;选课、退课、查看课程信息、查看选课情况等操作 教师&#xff1a;查看选课名单等操作 管理员&#xff1a;课程管理等操作 实体关系模式图 关…

js计算某个时间距离当前时间多少天,少于7天红色展示

效果图 后端返回数据格式 info:{vip_validity:"2027-09-07" }<div>到期时间&#xff1a;{{ info.vip_validity }}, 剩余<span :class"countdownDays(info.vip_validity) < 7 ? surplus : ">{{ !!info.vip_validity ? countdownDays(inf…