练习题(2024/5/9)

1删除二叉搜索树中的节点

给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。

一般来说,删除节点可分为两个步骤:

  1. 首先找到需要删除的节点;
  2. 如果找到了,删除它。

示例 1:

输入:root = [5,3,6,2,4,null,7], key = 3
输出:[5,4,6,2,null,null,7]
解释:给定需要删除的节点值是 3,所以我们首先找到 3 这个节点,然后删除它。
一个正确的答案是 [5,4,6,2,null,null,7], 如下图所示。
另一个正确答案是 [5,2,6,null,4,null,7]。

示例 2:

输入: root = [5,3,6,2,4,null,7], key = 0
输出: [5,3,6,2,4,null,7]
解释: 二叉树不包含值为 0 的节点

示例 3:

输入: root = [], key = 0
输出: []

提示:

  • 节点数的范围 [0, 104].
  • -105 <= Node.val <= 105
  • 节点值唯一
  • root 是合法的二叉搜索树
  • -105 <= key <= 105

思路:

二叉搜索树中删除节点遇到的情况:

  • 第一种情况:没找到删除的节点,遍历到空节点直接返回了
  • 找到删除的节点
    • 第二种情况:左右孩子都为空(叶子节点),直接删除节点, 返回NULL为根节点
    • 第三种情况:删除节点的左孩子为空,右孩子不为空,删除节点,右孩子补位,返回右孩子为根节点
    • 第四种情况:删除节点的右孩子为空,左孩子不为空,删除节点,左孩子补位,返回左孩子为根节点
    • 第五种情况:左右孩子节点都不为空,则将删除节点的左子树头结点(左孩子)放到删除节点的右子树的最左面节点的左孩子上,返回删除节点右孩子为新的根节点。

  1. 确定递归函数及其参数:

    • 递归函数 deleteNode 接受两个参数:二叉搜索树的根节点 root 和要删除的节点值 key。它返回删除节点后的二叉搜索树的根节点。
  2. 定义递归终止条件:

    • 如果当前节点为空,说明已经搜索到叶子节点或树为空,直接返回空指针。
    • 如果当前节点的值等于要删除的值,则根据节点的情况进行删除操作,并返回相应的节点。
  3. 拆分问题并递归求解:

    • 如果要删除的值小于当前节点的值,则在左子树中递归删除。
    • 如果要删除的值大于当前节点的值,则在右子树中递归删除。
  4. 合并子问题的结果:

    • 如果删除的是叶子节点,则直接删除并返回空指针。
    • 如果删除的节点只有一个子节点,则将子节点提升为父节点。
    • 如果删除的节点有两个子节点,则找到右子树中最小的节点,将其替换当前节点,并在右子树中删除这个最小节点。
  5. 清理和整理数据:

    • 在删除节点后,需要释放被删除节点的内存空间,确保程序的正确性和内存管理。

代码:

class Solution {
public:// 定义删除节点函数,返回删除节点后的根节点TreeNode* deleteNode(TreeNode* root, int key) {// 如果根节点为空,直接返回空指针if (root == nullptr) return root;// 如果当前节点的值等于要删除的值if (root->val == key) {// 情况1:当前节点没有左右子节点,直接删除当前节点并返回空指针if (root->left == nullptr && root->right == nullptr) {delete root;return nullptr;}// 情况2:当前节点没有右子节点,将左子节点提升为新的根节点else if (root->right == nullptr) {auto retNode = root->left;delete root;return retNode;}// 情况3:当前节点没有左子节点,将右子节点提升为新的根节点else if (root->left == nullptr) {auto retNode = root->right;delete root;return retNode;}// 情况4:当前节点既有左子节点又有右子节点else {// 找到右子树中最小的节点作为替代节点TreeNode* cur = root->right;while (cur->left != nullptr) {cur = cur->left;}// 将替代节点的左子树连接到当前节点的左子树cur->left = root->left;TreeNode* temp = root;// 将当前节点替换为右子树的根节点root = root->right;delete temp; // 释放当前节点的内存return root;}}// 如果要删除的值小于当前节点的值,在左子树中继续删除if (root->val > key) root->left = deleteNode(root->left, key);// 如果要删除的值大于当前节点的值,在右子树中继续删除if (root->val < key) root->right = deleteNode(root->right, key);// 返回删除节点后的根节点return root;}
};

2把二叉搜索树转换为累加树

给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(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]

提示:

  • 树中的节点数介于 0 和 104 之间。
  • 每个节点的值介于 -104 和 104 之间。
  • 树中的所有值 互不相同 。
  • 给定的树为二叉搜索树。

一棵二叉搜索树,二叉搜索树啊,这是有序的啊。

那么有序的元素如何求累加呢?

其实这就是一棵树,大家可能看起来有点别扭,换一个角度来看,这就是一个有序数组[2, 5, 13],求从后到前的累加数组,也就是[20, 18, 13],是不是感觉这就简单了。

为什么变成数组就是感觉简单了呢?

因为数组大家都知道怎么遍历啊,从后向前,挨个累加就完事了,这换成了二叉搜索树,看起来就别扭了一些是不是。

那么知道如何遍历这个二叉树,也就迎刃而解了,从树中可以看出累加的顺序是右中左,所以我们需要反中序遍历这个二叉树,然后顺序累加就可以了

利用了中序遍历BST的特性,从大到小遍历节点,并将每个节点的值更新为当前节点值加上其右子树所有节点的值之和,即将每个节点的值替换为原始BST中比它大的所有节点值之和。

解题思路如下:

  1. 确定递归函数及其参数:

    • 递归函数 convertBST 接受一个参数:二叉搜索树的根节点 root,并返回转换后的根节点。
  2. 定义递归终止条件:

    • 如果当前节点为空,直接返回。
    • 递归函数中没有其他终止条件,因为需要遍历整棵树。
  3. 拆分问题并递归求解:

    • 采用右-中-左的顺序递归遍历BST。首先遍历右子树,然后更新当前节点的值,最后遍历左子树。
  4. 合并子问题的结果:

    • 在遍历过程中,每次更新当前节点的值为当前节点值加上前一个节点的值(即右子树节点的值之和)。
    • 由于采用了中序遍历,因此在更新节点值时,已经确保了比当前节点大的所有节点的值已经被加到了当前节点。
  5. 清理和整理数据:

    • 递归过程中不需要进行额外的数据清理或整理。

代码:

class Solution {
private:// 前一个节点的值,初始为0int pre = 0;// 定义中序遍历函数void traversal(TreeNode* cur) {// 如果当前节点为空,直接返回if (cur == nullptr) return;// 先遍历右子树traversal(cur->right);// 更新当前节点的值为当前节点值加上前一个节点的值cur->val += pre;// 更新前一个节点的值为当前节点值pre = cur->val;// 遍历左子树traversal(cur->left);}public:// 定义转换BST函数,返回转换后的根节点TreeNode* convertBST(TreeNode* root) {// 重置前一个节点值为0pre = 0;// 执行中序遍历traversal(root);// 返回根节点return root;}
};

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

给你一个整数数组 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 按 严格递增 顺序排列

递归思路:

  1. 确定递归函数及其参数: 首先确定递归函数,本例中为 traversal 函数,参数包括传入的有序数组 nums,以及当前子数组的左右边界 left 和 right

  2. 定义递归终止条件: 在递归函数内部,需要首先检查递归终止的条件。在这个例子中,终止条件是当左边界 left 大于右边界 right 时,说明当前子数组为空,此时返回空指针。

  3. 拆分问题并递归求解: 在递归函数内部,首先确定当前子数组的中间位置 mid,然后以该位置的元素构建当前子树的根节点。接着,分别对左右子数组进行递归调用,我们递归地构建左子树和右子树,分别传入左半部分和右半部分的数组,并更新左右子节点。最终返回根节

代码:

class Solution {
private:// 定义私有函数,用于递归构建平衡二叉搜索树TreeNode* traversal(vector<int>& nums, int left, int right) {// 如果左边界大于右边界,返回空指针if (left > right) return nullptr;// 计算中间位置int mid = (left + right) / 2;// 创建根节点TreeNode* root = new TreeNode(nums[mid]);// 递归构建左子树root->left = traversal(nums, left, mid - 1);// 递归构建右子树root->right = traversal(nums, mid + 1, right);// 返回根节点return root;}public:// 定义公有函数,将有序数组转换为平衡二叉搜索树TreeNode* sortedArrayToBST(vector<int>& nums) {// 调用递归函数构建平衡二叉搜索树TreeNode* root = traversal(nums, 0, nums.size() - 1);// 返回根节点return root;}
};

4银行账户概要 II

表: Users

+--------------+---------+
| Column Name  | Type    |
+--------------+---------+
| account      | int     |
| name         | varchar |
+--------------+---------+
account 是该表的主键(具有唯一值的列)。
该表的每一行都包含银行中每个用户的帐号。
表中不会有两个用户具有相同的名称。

表: Transactions

+---------------+---------+
| Column Name   | Type    |
+---------------+---------+
| trans_id      | int     |
| account       | int     |
| amount        | int     |
| transacted_on | date    |
+---------------+---------+
trans_id 是该表主键(具有唯一值的列)。
该表的每一行包含了所有账户的交易改变情况。
如果用户收到了钱, 那么金额是正的; 如果用户转了钱, 那么金额是负的。
所有账户的起始余额为 0。

编写解决方案,  报告余额高于 10000 的所有用户的名字和余额. 账户的余额等于包含该账户的所有交易的总和。

返回结果表单 无顺序要求 。

查询结果格式如下例所示。

示例 1:

输入:
Users table:
+------------+--------------+
| account    | name         |
+------------+--------------+
| 900001     | Alice        |
| 900002     | Bob          |
| 900003     | Charlie      |
+------------+--------------+Transactions table:
+------------+------------+------------+---------------+
| trans_id   | account    | amount     | transacted_on |
+------------+------------+------------+---------------+
| 1          | 900001     | 7000       |  2020-08-01   |
| 2          | 900001     | 7000       |  2020-09-01   |
| 3          | 900001     | -3000      |  2020-09-02   |
| 4          | 900002     | 1000       |  2020-09-12   |
| 5          | 900003     | 6000       |  2020-08-07   |
| 6          | 900003     | 6000       |  2020-09-07   |
| 7          | 900003     | -4000      |  2020-09-11   |
+------------+------------+------------+---------------+
输出:
+------------+------------+
| name       | balance    |
+------------+------------+
| Alice      | 11000      |
+------------+------------+
解释:
Alice 的余额为(7000 + 7000 - 3000) = 11000.
Bob 的余额为1000.
Charlie 的余额为(6000 + 6000 - 4000) = 8000.

代码:

select  name,sum(Transactions.amount)as balancefrom Users  left join Transactions on Users.account=Transactions.accountgroup by Transactions.account having sum(Transactions.amount)>10000

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

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

相关文章

第十二章 信息安全

这里写目录标题 1.防火墙2.病毒3.网络攻击4.网络安全 1.防火墙 认为内部网络安全&#xff0c;外部网络不安全 控制&#xff0c;审计&#xff0c;报警&#xff0c;反应 内部可以访问外部&#xff0c;外部不能访问内部 DMZ&#xff1a;存储公用服务器 发展阶段&#xff1a; 包过…

融知财经:期货在哪里可以交易?期货交易有哪些交易规则?

作为当前金融市场的一种投资方式&#xff0c;期货只适合一些投资者&#xff0c;比如想获得高收益的投资者&#xff0c;因为期货的风险系数很高。但是很多投资者还不知道期货的意思&#xff0c;在一个固定的交易场所&#xff0c;期货是买卖标准化商品或金融资产的远期合约的交易…

RK3568 学习笔记 : u-boot 下通过设置 env ethact 设置当前工作的以太网设备

前言 正点原子 &#xff1a;RK3568 开发板 atompi-ca1 默认有两个网口&#xff0c;通过 u-boot mii 命令&#xff0c;可以查看 网口信息 > mii device MII devices: ethernetfe010000 ethernetfe2a0000 Current device: ethernetfe010000u-boot 下的以太网&#xff0c;不同…

JAVA 学习·泛型(一)

基本概念 引言 泛型&#xff08;Generic&#xff09;指可以把类型参数化&#xff0c;这个能力使得我们可以定义带类型参数的泛型类、泛型接口、泛型方法&#xff0c;随后编译器会用唯一的具体类型替换它。主要优点是在编译时而不是运行时检测出错误。泛型类或方法允许用户指定…

HA-MAc,透明质酸-甲基丙烯酸酯可用于制备具有交联能力的透明质酸基材料

【基本信息】 Hyaluronate Methacrylate&#xff08;甲基丙烯酸酯化透明质酸&#xff0c;简称HA-MAc&#xff09;是一种重要的生物材料 中文名称&#xff1a;甲基丙烯酸酯化透明质酸、透明质酸-甲基丙烯酸酯 英文名称&#xff1a;Hyaluronate Methacrylate、HA-MAc 分子量&…

matlab实现K均值聚类

在MATLAB中实现聚类分析&#xff0c;可以使用MATLAB内置的聚类函数&#xff0c;如kmeans&#xff08;用于K均值聚类&#xff09;&#xff0c;linkage和cluster&#xff08;用于层次聚类&#xff09;&#xff0c;或者使用MATLAB的统计和机器学习工具箱中的其他函数。 以下是一个…

软件设计师考试---访问控制列表、堆,栈和堆栈、防火墙、数据流图、嵌入式操作、绑定方式、uml、模式、传输协议

访问控制列表 访问控制列表&#xff08;Access Control List&#xff0c;ACL&#xff09; 是一种用于控制对资源&#xff08;如文件、目录、网络资源等&#xff09;访问权限的方法。ACL是在计算机安全领域广泛使用的概念&#xff0c;它允许系统管理员定义哪些用户或系统进程有…

男人圣经 10

男人圣经 10 行业基因 你在对行业、客户群体、事情、核心优势上的高感知力 行业基因 你在对行业、客户群体、事情、核心优势上的高感知力 灵性&#xff0c;我感觉是对人、对事情、对行业的感知力&#xff0c;这就是你的天赋程度。 比如情圣&#xff0c;他比女人更懂自己&am…

python代码自动生成器原理 python 生成器原理

python生成器原理剖析 函数的调用满足“后进先出”的原则&#xff0c;也就是说&#xff0c;最后被调用的函数应该第一个返回&#xff0c;函数的递归调用就是一个经典的例子。显然&#xff0c;内存中以“后进先出”"方式处理数据的栈段是最适合用于实现函数调用的载体&…

使用Maven对Scala独立应用程序进行编译打包

一、 安装Maven 1.解压&#xff0c;移动安装包 sudo tar -zxf ~/apache-maven-3.9.6-bin.tar.gz -C /usr/local/ cd /usr/local/ sudo mv apache-maven-3.9.6/ ./maven-3.9.6 sudo chown -R qiangzi ./maven-3.9.6 二、Scala应用程序代码 1.在终端中执行如下命令创建一个文…

【C++】C++11--- lambda表达式

目录 Lambda表达式概述 Lambda表达式语法定义 Lambda表达式参数详解 Lambda捕获列表 捕获列表总结 Lambda参数列表 可变规则mutable lambda表达式原理 Lambda表达式概述 当对自定义类型的数据集合进行排序时&#xff0c;需要根据自定义类型的不同属性去实现不同的排序方…

MySQL变量声明与使用

#MySQL变量声明与使用 变量命名规范 #1 标识符不能以数字作为开头 #2 只能使用_或着$符号 #3 不允许使用系统关键字 set userName 刘德华; select userName:刘青云;#将赋值与查询结合 查询变量/使用变量 匿名的时候建议加上as select userName as 读取到的userName变量值; 整…

百病之源,根在肝脏!4种养肝法,助您对症养肝,越养越健康~

如今生活节奏比较快&#xff0c;人们的身体和精神都承受着巨大的压力&#xff0c;熬夜加班、喝酒应酬、通宵上网等&#xff0c;这些习惯都在悄悄损耗我们的肝脏&#xff0c;使得大家长期处于亚健康的边缘&#xff01; 中医讲&#xff0c;百病之源&#xff0c;根在肝脏。肝不好…

二总线,替代传统485总线通讯,主站设计

二总线通信设计专栏 《二总线&#xff0c;替代传统485总线通讯&#xff0c;选型及应用-CSDN博客》《二总线&#xff0c;替代传统485总线通讯&#xff0c;低成本直流载波方案实现及原理-CSDN博客》《二总线&#xff0c;替代传统485总线通讯&#xff0c;调试避坑指南之最大的电流…

深度学习:基于TensorFlow 和 Keras,使用神经网络回归模型预测 IPL 分数

前言 系列专栏&#xff1a;机器学习&#xff1a;高级应用与实践【项目实战100】【2024】✨︎ 在本专栏中不仅包含一些适合初学者的最新机器学习项目&#xff0c;每个项目都处理一组不同的问题&#xff0c;包括监督和无监督学习、分类、回归和聚类&#xff0c;而且涉及创建深度学…

专业习惯:善于写注释,追求极致

写好注释&#xff0c;是一件极其不容易的事情&#xff0c;也被许多人忽略。 写好注释优点如下&#xff1a;1&#xff09;抽象表达自己要干的事情加深自己的印象&#xff1b;2&#xff09;当再次面对自己的代码时&#xff0c;能够让自己和他人尽快熟悉&#xff0c;减少重复理解原…

css类名冲突-css in js

css in js css in js 的核心思想是&#xff1a;用一个JS对象来描述样式&#xff0c;而不是css样式表 例如下面的对象就是一个用于描述样式的对象&#xff1a; const styles {backgroundColor: "#f40",color: "#fff",width: "400px",height: …

关于linux的进阶配置(mysql)你需要知道(1)-认识mysql

1、基本概念 数据库系统(DBS) 数据库管理系统(DBMS) &#xff1a;SQL server ,mysql 数据库管理员(DBA) 2、经典数据模型: 网状模型 层次模型 关系模型 3、主流的数据库: (1)SQL Server(微软公司产品) 面向Windows操作系统 简单、易用 (2)Oracle(甲骨文公司产品) 面向所有主…

Cesium 问题:billboard 加载未出来

文章目录 问题分析问题 接上篇 Cesium 展示——图标的依比例和不依比例缩放,使用加载 billboard 时,怀疑是路径的原因导致未加载成功 分析 原先