代码随想录day21 二叉树最后一天 || 669修剪二叉树 108将有序数组转变为平衡搜索二叉树 538把搜索二叉树变为累加二叉树

news2024/11/15 10:07:55

669修剪二叉树 

力扣题目链接

题目描述:

给你二叉搜索树的根节点 root ,同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树,使得所有节点的值在[low, high]中。修剪树 不应该 改变保留在树中的元素的相对结构 (即,如果没有被移除,原有的父代子代关系都应当保留)。 可以证明,存在 唯一的答案 。

所以结果应当返回修剪好的二叉搜索树的新的根节点。注意,根节点可能会根据给定的边界发生改变。

示例 1:

输入:root = [1,0,2], low = 1, high = 2
输出:[1,null,2]

示例 2:

输入:root = [3,0,4,null,2,null,null,1], low = 1, high = 3
输出:[3,2,null,1]

代码:

 class Solution {  
public:  
    TreeNode* trimBST(TreeNode* root, int low, int high) {  
        if (root == nullptr) return nullptr;  

        
        if (root->val < low) {  
            return trimBST(root->right, low, high);  
        }  
       

        if (root->val > high) {  
            return trimBST(root->left, low, high);  
        }  

         
        root->left = trimBST(root->left, low, high);  
        root->right = trimBST(root->right, low, high);  

        return root;  
    }  
};  

代码解释:
 

详细解释

  1. Base Case:

    • 如果当前节点是空 (nullptr),直接返回空,因为没有树需要修剪。
  2. 修剪逻辑:

    • 节点值小于 low
      如果当前节点值 root->val < low,这意味着当前节点和它的左子树所有节点都小于 low,需要被修剪掉。所以,我们修剪右子树。

       

      if (root->val < low) { TreeNode* rightTrimmed = trimBST(root->right, low, high); return rightTrimmed; }

      这里,对右子树调用 trimBST 递归函数,并将修剪后的右子树赋值给 rightTrimmed,然后释放当前节点,返回修剪后的右子树。

    • 节点值大于 high
      如果当前节点值 root->val > high,这意味着当前节点和它的右子树所有节点都大于 high,需要被修剪掉。所以,我们修剪左子树。

       

      if (root->val > high) { TreeNode* leftTrimmed = trimBST(root->left, low, high); return leftTrimmed; }

      这里,对左子树调用 trimBST 函数,并将修剪后的左子树赋值给 leftTrimmed,然后释放当前节点,返回修剪后的左子树。

    • 节点值在区间 [low, high] 之间:
      如果当前节点的值在 [low, high] 之间,那么当前节点是需要保留的节点。但是仍然需要继续修剪其左右子树。

       

      root->left = trimBST(root->left, low, high); root->right = trimBST(root->right, low, high); return root;

      这里,通过递归处理左右子树,并将返回的修剪后的子树赋值给当前节点的左右子节点,最后返回当前节点。

108将有序数组转变为平衡搜索二叉树

力扣题目链接

题目描述:

给你一个整数数组 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] 都是高度平衡二叉搜索树。

代码:

#include <vector>  

// 树节点的定义  
struct TreeNode {  
    int val;               // 节点的值  
    TreeNode *left;        // 左子节点  
    TreeNode *right;       // 右子节点  
    TreeNode() : val(0), left(nullptr), right(nullptr) {}     // 无参构造函数  
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} // 有参构造函数  
    TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} // 完整构造函数  
};  

class Solution {  
public:  
    // 递归构造 BST 的辅助函数  
    TreeNode* travesal(std::vector<int>& nums, int left, int right) {  
        // 基准条件:如果左索引超过右索引,返回空指针  
        if(left > right) return nullptr;  

        // 计算中间索引,避免整数溢出的安全写法  
        int mid = left + (right - left) / 2;  

        // 创建根节点,值为数组中间位置的值  
        TreeNode* root = new TreeNode(nums[mid]);  

        // 递归构造左子树,范围为[left, mid-1]  
        root->left = travesal(nums, left, mid - 1);  

        // 递归构造右子树,范围为[mid + 1, right]  
        root->right = travesal(nums, mid + 1, right);  

        // 返回根节点  
        return root;  
    }  

    // 主函数,将有序数组转换为 BST  
    TreeNode* sortedArrayToBST(std::vector<int>& nums) {  
        // 初始调用辅助函数,范围为整个数组  
        int left = 0;  
        int right = nums.size() - 1;  

        // 获取并返回构造出的 BST 的根节点  
        TreeNode* root = travesal(nums, left, right);  
        return root;  
    }  
};  

详细解释

  1. TreeNode 结构体
    定义了树节点,其中 val 是节点的值,left 和 right 分别是左子节点和右子节点。无参构造函数将节点默认初始化为值 0 和空子节点,有参构造函数将节点的值初始化为给定值,最后一个构造函数同时初始化节点的值和子节点。

  2. travesal 函数(递归辅助函数)
    这个函数递归地构建 BST:

    • 基准条件:当 left 超过 right 时,返回空指针,表示该子树为空。
    • 中间索引:计算中间索引 mid,它是子数组的中间元素的位置。
    • 创建根节点:使用中间元素创建根节点。
    • 分别递归构建左子树和右子树:递归调用 travesal 函数,分别构建左子树(范围为 left 到 mid-1)和右子树(范围为 mid+1 到 right)。
    • 返回根节点:返回该子树的根节点。
  3. sortedArrayToBST 函数(主函数)
    这是主函数,调用递归辅助函数来构建 BST:

    • 初始化 left 和 right 索引,分别为数组的起始和结束位置。
    • 调用 travesal 函数来构建 BST,并得到根节点。
    • 返回最终构建好的根节点。

举个例子:

假设输入的有序数组是 [1, 2, 3, 4, 5, 6, 7],我们将通过该方法将其转换为高度平衡的 BST。

  1. 取数组的中间元素 4 作为根节点。
  2. 将左半部分 [1, 2, 3] 递归构建左子树:
    • 子数组 [1, 2, 3] 的中间元素 2 作为左子树的根节点。
    • 子数组 [1] 递归构建左子树:1 作为左子树的根节点。
    • 子数组 [3] 递归构建右子树:3 作为右子树的根节点。
  3. 将右半部分 [5, 6, 7] 递归构建右子树:
    • 子数组 [5, 6, 7] 的中间元素 6 作为右子树的根节点。
    • 子数组 [5] 递归构建左子树:5 作为左子树的根节点。
    • 子数组 [7] 递归构建右子树:7 作为右子树的根节点。

 

538把搜索二叉树变为累加二叉树

力扣题目链接

题目描述:

给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。

提醒一下,二叉搜索树满足下列约束条件:

  • 节点的左子树仅包含键 小于 节点键的节点。
  • 节点的右子树仅包含键 大于 节点键的节点。
  • 左右子树也必须是二叉搜索树。

注意:本题和 1038: . - 力扣(LeetCode) 相同

示例 1:

输入:[4,1,6,0,2,5,7,null,null,null,3,null,null,null,8]
输出:[30,36,21,36,35,26,15,null,null,null,33,null,null,null,8]

示例 2:

输入:root = [0,null,1]
输出:[1,null,1]

示例 3:

输入:root = [1,0,2]
输出:[3,3,2]

示例 4:

输入:root = [3,2,4,1]
输出:[7,9,4,10]

代码:

class Solution {
public:
    int pre=0;
    TreeNode* convert(TreeNode* cur){
        if(cur==NULL)return NULL;
        convert(cur->right);
        cur->val+=pre;
        pre=cur->val;
        convert(cur->left);
        return cur;
    }
    TreeNode* convertBST(TreeNode* root) {
       
       return convert(root);
    }
};

这题需要注意的是遍历顺序,逆中序遍历,其他的没什么很简单

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

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

相关文章

Anything LLM ,构建自己的 RAG 架构 LLM,学习自己的知识库

本心、输入输出、结果 文章目录 Anything LLM ,构建自己的 RAG 架构 LLM,学习自己的知识库前言什么是Anything LLM?主要功能与技术原理功能亮点技术原理安装与使用方法初始设置模型部署案例应用企业知识管理个性化教育助手内容创作助手Anything LLM 开源新Anything LLM ,构…

DolphinDB Web 端权限管理:可视化操作指南

在现代数据库管理中&#xff0c;高效和直观的权限管理对于用户的数据安全是至关重要的。过去 DolphinDB 用户需要依赖系统脚本来管理用户和权限&#xff0c;这对于缺乏技术背景的管理员来说既复杂又容易出错。 为了提升用户体验和操作效率&#xff0c;DolphinDB 目前在 Web 上…

解决nvm use无效问题

首先安装先确定没错。nvm安装教程 问题&#xff1a;nvm use 后 node和npm均无法使用&#xff0c;nvm list也没有*号 原因&#xff1a;nvm目录下没有nodejs文件夹 解决办法&#xff1a;先nvm install 一个版本&#xff0c;复制&#xff0c;改名nodejs&#xff0c;比如我这里是复…

unity2D游戏开发02添加组件移动玩家

添加组件 给PlayGame和EnemyObject添加组件BoxCollider 2D碰撞器&#xff0c;不用修改参数 给PlayGame添加组件Rigibody 2D 设置数据 添加EnemyObject&#xff0c;属性如下 Edit->project setting->Physics 2D 将 y的值改为0 给playerObject添加标签 新建层 将PlayerObj…

MacOS安装SDKMan管理Java版本

文章目录 1 简介2 安装与卸载2.1 安装2.2 卸载 3 使用3.1 查看其他工具&#xff1a;支持 Ant, Maven 等3.2 查看Java版本3.3 安装Java&#xff0c;加上相关的版本3.4 设置Java版本(全局)3.5 只在当前窗口生效3.6 卸载1 默认环境无法卸载 4 jdk安装的位置5 与IDEA集成参考 1 简介…

【目标检测实验系列】EMA高效注意力机制,融合多尺度特征,助力YOLOv5检测模型涨点(文内附源码)

1. 文章主要内容 本篇博客主要涉及多尺度高效注意力机制&#xff0c;融合到YOLOv5s模型中&#xff0c;增加模型提取多尺度特征的能力&#xff0c;助力模型涨点。&#xff08;通读本篇博客需要7分钟左右的时间&#xff09;。 2. 简要概括 论文地址&#xff1a;EMA论文地址 如下…

使用 VMware vCenter Server(vSphere Client)迁移 ESXi 虚拟机

我需要将虚拟机 k8s-dev-node4从 ESXi 主机 192.168.1.161 迁移到 ESXi 主机 192.168.1.162 上&#xff0c;使用 VMware vCenter Server&#xff08;vSphere Client&#xff09;在浏览器上可视化操作&#xff0c;将这个需求变的非常简单。 1、选中需要迁移的虚拟机&#xff0c…

k8s部署rabbitmq集群

1 部署集群 1.1 安装 # 创建一个中间件的命名空间 kubectl create namespace middleware # 创建ConfigMap,包含RabbitMQ的配置文件内容 kubectl apply -f rabbitmq-configmap.yaml # 配置用于存储RabbitMQ数据的PersistentVolume&#xff08;PV&#xff09;和PersistentVolum…

系统架构设计师教程 第4章 信息安全技术基础知识-4.3 信息安全系统的组成框架4.4 信息加解密技术-解读

系统架构设计师教程 第4章 信息安全技术基础知识-4.3 信息安全系统的组成框架 4.3 信息安全系统的组成框架4.3.1 技术体系4.3.1.1 基础安全设备4.3.1.2 计算机网络安全4.3.1.3 操作系统安全4.3.1.4 数据库安全4.3.1.5 终端安全设备4.3.2 组织机构体系4.3.3 管理体系4.4 信息加…

机器学习(五) -- 无监督学习(1) --聚类2

系列文章目录及链接 上篇&#xff1a;机器学习&#xff08;五&#xff09; -- 无监督学习&#xff08;1&#xff09; --聚类1 下篇&#xff1a; 前言 tips&#xff1a;标题前有“***”的内容为补充内容&#xff0c;是给好奇心重的宝宝看的&#xff0c;可自行跳过。文章内容被…

微服务(网关路由)

目录 一&#xff1a;网关路由 1&#xff1a;认识网关 2&#xff1a;快速入门 2.1&#xff1a;创建项目 2.2&#xff1a;引入依赖 2.3&#xff1a;启动类 2.4&#xff1a;路由配置 2.5&#xff1a;测试 3&#xff1a;路由过滤 二&#xff1a;网关登录校验 1&…

OpenWrt 为软件包和docker空间扩容

参考资料 【openwrt折腾日记】解决openwrt固件刷入后磁盘空间默认小的问题&#xff0c;关联openwrt磁盘扩容空间扩容【openwrt分区扩容】轻松解决空间可用不足的尴尬丨老李一瓶奶油的YouTube 划分空间 参考一瓶奶油的YouTube 系统 -> 磁盘管理 -> 磁盘 -> 修改 格…

探索Linux-1

Linux是什么&#xff1f; Linux是一个开源的操作系统内核&#xff0c;由林纳斯托瓦兹&#xff08;Linus Torvalds&#xff09;于1991年首次发布。它基于Unix操作系统&#xff0c;但提供了更多的自由和灵活性。Linux内核是操作系统的核心部分&#xff0c;负责管理系统资源、处理…

编程中的智慧四:设计模式总览

前面三篇我们通过从一些零散的例子&#xff0c;和简单应用来模糊的感受了下设计模式在编程中的智慧&#xff0c;从现在开始正式进入设计模式介绍&#xff0c;本篇将从设计模式的7大原则、设计模式的三大类型、与23种设计模式的进行总结&#xff0c;和描述具体意义。 设计模式体…

LeetCode 860柠檬水找零(贪心算法)/406根据身高重建队列(贪心算法)

1. 柠檬水找零 思路分析 只需要维护三种金额的数量&#xff0c;5&#xff0c;10和20。 有如下三种情况&#xff1a; 情况一&#xff1a;账单是5&#xff0c;直接收下。情况二&#xff1a;账单是10&#xff0c;消耗一个5&#xff0c;增加一个10情况三&#xff1a;账单是20&am…

(35)远程识别(又称无人机识别)(二)

文章目录 前言 4 ArduRemoteID 5 终端用户数据的设置和使用 6 测试 7 为OEMs添加远程ID到ArduPilot系统的视频教程 前言 在一些国家&#xff0c;远程 ID 正在成为一项法律要求。以下是与 ArduPilot 兼容的设备列表。这里(here)有一个关于远程 ID 的很好解释和常见问题列表…

【linux】Shell脚本三剑客之awk命令的详细用法攻略

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全…

[用AI日进斗金系列③]用CodeFlying在企微接单自动生成一个固定资产管理系统

今天是【日进斗金】系列的第三期文章。 给新朋友简单介绍一下&#xff0c;我们这个系列主要是教大家如何在企业微信的工作台上接单赚米。 详细介绍可以看看前两期的文章 [用AI日进斗金系列]用码上飞在企微接单开发一个项目管理系统&#xff01;-CSDN博客 [用AI日进斗金系列…

【Android】性能实践—编码优化与布局优化学习笔记

【Android】性能实践—编码优化与布局优化学习笔记 编码优化 使用场景 如果需要拼接字符串&#xff0c;优先使用StringBuffer和StringBuilder进行凭借&#xff0c;他们的性能优于直接用加号进行拼接&#xff0c;因为使用加号连接符会创建多余的对象一般情况下使用基本数据类…

有监督学习基础

基本概念 给定输入有为&#xff08;x,y&#xff09;&#xff0c;其中x表示学习特征&#xff0c;y表示输出&#xff0c;m表示输入总数&#xff0c;有监督学习旨在根据输入建立能够预测可能输出的模型&#xff0c;大致可以分为回归和分类两种&#xff0c;代表可能输出是无限的或…