练习题(2024/4/29)

 在深度优先遍历中:有三个顺序,前中后序遍历 这里前中后,其实指的就是中间节点的遍历顺序,只要记住 前中后序指的就是中间节点的位置就可以了。

如图

1二叉树的前序遍历

给你二叉树的根节点 root ,返回它节点值的 前序 遍历。

示例 1:

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

示例 2:

输入:root = []
输出:[]

示例 3:

输入:root = [1]
输出:[1]

示例 4:

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

示例 5:

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

提示:

  • 树中节点数目在范围 [0, 100] 内
  • -100 <= Node.val <= 100
递归思路:

递归是一种在算法中使用函数自身来解决问题的方法。在递归算法中,函数会重复调用自身来处理问题的每一步,直到达到某个终止条件为止。递归算法通常包括三个重要部分:

  1. 确定递归函数的参数和返回值:确定哪些参数是递归过程中需要处理的,以及每次递归的返回值是什么进而确定递归函数的返回类型。

  2. 确定终止条件:为了避免无限循环或栈溢出错误,在递归算法中必须定义递归终止的条件,当满足终止条件时递归停止。

  3. 确定单层递归的逻辑:确定每一层递归需要处理的信息,并实现递归过程。通常在单层递归的逻辑中包含当前节点的处理逻辑以及对子节点的递归调用。

在递归算法中,需要注意以下几点:

  1. 确定递归函数的参数和返回值:在这段代码中,递归函数的参数为当前节点指针和存储节点值的数组,返回类型为void。这样做可以处理当前节点的值并在递归过程中更新结果数组。

  2. 确定终止条件:在递归中,一定要有终止条件,否则会导致栈溢出错误。在这段代码中,终止条件是当前节点为空(cur == NULL),此时直接返回,结束当前递归。

  3. 确定单层递归的逻辑:在前序遍历中,需要先处理当前节点的值,然后递归遍历左子树,最后递归遍历右子树。这种顺序符合前序遍历的要求。

代码:

class Solution {
public:// 定义一个辅助函数,用来递归遍历二叉树并将节点值存入结果数组void traversal(TreeNode* cur, vector<int>& vec) {// 若当前节点为空,则返回if (cur == NULL) return;vec.push_back(cur->val);    // 中序遍历,将当前节点的值加入结果数组traversal(cur->left, vec);  // 递归遍历左子树traversal(cur->right, vec); // 递归遍历右子树}// 定义前序遍历函数,返回一个存储节点值的数组vector<int> preorderTraversal(TreeNode* root) {vector<int> result;// 从根节点开始遍历traversal(root, result); // 调用辅助函数,从根节点开始前序遍历return result;}
};
 迭代思路:

迭代的思想是通过循环重复执行某段代码来解决问题,而不是通过递归的方式调用函数自身。迭代通常通过循环结构来实现,每次循环迭代处理一部分信息,直到达到预定的终止条件为止。

栈的特点是一种后进先出(LIFO)的数据结构,即最后入栈的元素会最先出栈

前序遍历的迭代法思路是通过使用栈数据结构来模拟递归的过程。具体步骤如下:

  1. 创建一个栈(stack)用于存储节点指针和一个结果数组(result)用于存储节点值。

  2. 将根节点压入栈中。

  3. 循环执行以下操作,直到栈为空:
    a. 弹出栈顶节点(当前访问的节点)。
    b. 将节点值加入结果数组。
    c. 如果节点的右子节点不为空,则将右子节点压入栈中。
    d. 如果节点的左子节点不为空,则将左子节点压入栈中。

  4. 遍历结束后,返回结果数组作为前序遍历的结果。

代码:

class Solution {
public:vector<int> preorderTraversal(TreeNode* root) {stack<TreeNode*> st;  // 定义栈用来存储节点指针vector<int> result;   // 定义结果数组if (root == NULL) return result;  // 如果根节点为空则直接返回空数组st.push(root);  // 将根节点压入栈中while (!st.empty()) {TreeNode* node = st.top();  // 获取栈顶节点st.pop();  // 弹出栈顶节点result.push_back(node->val);  // 将节点值加入结果数组if (node->right) st.push(node->right);  // 若右子节点不为空,则压入栈中if (node->left) st.push(node->left);  // 若左子节点不为空,则压入栈中}return result;  // 返回结果数组}
};

2二叉树的后序遍历

给你一棵二叉树的根节点 root ,返回其节点值的 后序遍历 

示例 1:

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

示例 2:

输入:root = []
输出:[]

示例 3:

输入:root = [1]
输出:[1]

提示:

  • 树中节点的数目在范围 [0, 100] 内
  • -100 <= Node.val <= 100
递归思路 代码:
class Solution {
public:// 定义一个辅助函数,用来递归遍历二叉树并将节点值存入结果数组(后序遍历)void traversal(TreeNode *cur, vector<int>& vec) {if (cur == nullptr) return;traversal(cur->left, vec);   // 递归遍历当前节点的左子树traversal(cur->right, vec);  // 递归遍历当前节点的右子树vec.push_back(cur->val);     // 将当前节点的值加入结果数组}// 定义后序遍历函数,返回一个存储节点值的数组vector<int> postorderTraversal(TreeNode* root) {vector<int> result;traversal(root, result);     // 开始后序遍历,将结果存入数组return result;}
};
迭代思路
  1. 栈的应用:题目要求实现二叉树的后序遍历,可以考虑使用栈来辅助实现。栈可以帮助我们模拟递归的过程,从而遍历树的节点。

  2. 迭代法的核心:迭代法的核心是通过循环结构不断处理节点,模拟递归的过程。在后序遍历中,节点的访问顺序是左子树、右子树、根节点,因此我们需要注意入栈的顺序。

  3. 遍历过程:从根节点开始,将根节点入栈。然后循环执行以下步骤:

    • 弹出栈顶节点,将其值加入结果数组。
    • 如果节点有右子节点,则将右子节点压入栈中。
    • 如果节点有左子节点,则将左子节点压入栈中。
  4. 结果反转:由于后序遍历的顺序是左子树、右子树、根节点,而我们入栈的顺序是根节点、右子节点、左子节点,因此得到的结果数组需要进行反转。

  5. 返回结果:最后返回反转后的结果数组即可。

代码:
class Solution {
public:vector<int> postorderTraversal(TreeNode* root) {stack<TreeNode*> st;  // 定义栈用来存储节点指针vector<int> result;   // 定义结果数组if (root == NULL) return result;  // 如果根节点为空则直接返回空数组st.push(root);  // 将根节点压入栈中while (!st.empty()) {TreeNode* node = st.top();  // 获取栈顶节点st.pop();  // 弹出栈顶节点result.push_back(node->val);  // 将节点值加入结果数组if (node->left) st.push(node->left);  // 若左子节点不为空,则压入栈中if (node->right) st.push(node->right);  // 若右子节点不为空,则压入栈中}reverse(result.begin(), result.end());  // 将结果数组反转,得到左右中的遍历顺序return result;  // 返回结果数组}
};

3二叉树的中序遍历

给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。

示例 1:

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

示例 2:

输入:root = []
输出:[]

示例 3:

输入:root = [1]
输出:[1]

提示:

  • 树中节点数目在范围 [0, 100] 内
  • -100 <= Node.val <= 100
递归思路 代码:
class Solution {
public:// 定义一个辅助函数,用来递归遍历二叉树并将节点值存入结果数组(中序遍历)void traversal(TreeNode* cur, vector<int>& vec) {if (cur == nullptr) return;traversal(cur->left, vec);      // 递归遍历当前节点的左子树vec.push_back(cur->val);        // 将当前节点的值加入结果数组traversal(cur->right, vec);     // 递归遍历当前节点的右子树}// 定义中序遍历函数,返回一个存储节点值的数组vector<int> inorderTraversal(TreeNode* root) {vector<int> result;traversal(root, result);        // 开始中序遍历,将结果存入数组return result;}
};
 迭代思路
  1. 栈的应用:使用栈来辅助实现中序遍历。栈可以帮助我们模拟递归的过程,从而遍历树的节点。

  2. 指针的运用:我们使用一个指针cur来遍历节点,初始时指向根节点。

  3. 循环遍历:我们使用一个while循环来遍历节点,直到当前节点为NULL且栈为空为止。在循环中,我们检查当前节点cur是否为空,以及栈是否为空。

  4. 处理当前节点

    • 如果cur不为空,说明还有左子树未遍历完,此时我们将当前节点入栈,并将cur指向其左子节点,以便继续向左遍历。
    • 如果cur为空,说明左子树已经遍历完毕,我们从栈中取出节点进行处理。这个节点就是当前子树的根节点,我们将其值加入结果数组,并将cur指向当前节点的右子节点。
  5. 遍历过程

    • 不断将左子节点入栈,直到到达最左侧节点。在入栈的过程中,保证了左、中、右的顺序。
    • 当一个节点的左子树全部处理完毕后,从栈中取出节点进行处理,然后转向处理右子树。
  6. 返回结果:最终返回中序遍历的结果数组。

代码:
class Solution {
public:vector<int> inorderTraversal(TreeNode* root) {vector<int> result;  // 定义结果数组stack<TreeNode*> st;  // 定义栈用来存储节点指针TreeNode* cur = root;  // 初始化当前节点为根节点while (cur != NULL || !st.empty()) {if (cur != NULL) {  // 如果当前节点不为空st.push(cur);  // 将当前节点入栈cur = cur->left;  // 移动到左子节点} else {cur = st.top();  // 从栈中取出节点进行处理st.pop();  // 弹出栈顶节点result.push_back(cur->val);  // 将节点值加入结果数组cur = cur->right;  // 移动到右子节点}}return result;  // 返回结果数组}
};

4学生们参加各科测试的次数

学生表: Students

+---------------+---------+
| Column Name   | Type    |
+---------------+---------+
| student_id    | int     |
| student_name  | varchar |
+---------------+---------+
在 SQL 中,主键为 student_id(学生ID)。
该表内的每一行都记录有学校一名学生的信息。

科目表: Subjects

+--------------+---------+
| Column Name  | Type    |
+--------------+---------+
| subject_name | varchar |
+--------------+---------+
在 SQL 中,主键为 subject_name(科目名称)。
每一行记录学校的一门科目名称。

考试表: Examinations

+--------------+---------+
| Column Name  | Type    |
+--------------+---------+
| student_id   | int     |
| subject_name | varchar |
+--------------+---------+
这个表可能包含重复数据(换句话说,在 SQL 中,这个表没有主键)。
学生表里的一个学生修读科目表里的每一门科目。
这张考试表的每一行记录就表示学生表里的某个学生参加了一次科目表里某门科目的测试。

查询出每个学生参加每一门科目测试的次数,结果按 student_id 和 subject_name 排序。

查询结构格式如下所示。

示例 1:

输入:
Students table:
+------------+--------------+
| student_id | student_name |
+------------+--------------+
| 1          | Alice        |
| 2          | Bob          |
| 13         | John         |
| 6          | Alex         |
+------------+--------------+
Subjects table:
+--------------+
| subject_name |
+--------------+
| Math         |
| Physics      |
| Programming  |
+--------------+
Examinations table:
+------------+--------------+
| student_id | subject_name |
+------------+--------------+
| 1          | Math         |
| 1          | Physics      |
| 1          | Programming  |
| 2          | Programming  |
| 1          | Physics      |
| 1          | Math         |
| 13         | Math         |
| 13         | Programming  |
| 13         | Physics      |
| 2          | Math         |
| 1          | Math         |
+------------+--------------+
输出:
+------------+--------------+--------------+----------------+
| student_id | student_name | subject_name | attended_exams |
+------------+--------------+--------------+----------------+
| 1          | Alice        | Math         | 3              |
| 1          | Alice        | Physics      | 2              |
| 1          | Alice        | Programming  | 1              |
| 2          | Bob          | Math         | 1              |
| 2          | Bob          | Physics      | 0              |
| 2          | Bob          | Programming  | 1              |
| 6          | Alex         | Math         | 0              |
| 6          | Alex         | Physics      | 0              |
| 6          | Alex         | Programming  | 0              |
| 13         | John         | Math         | 1              |
| 13         | John         | Physics      | 1              |
| 13         | John         | Programming  | 1              |
+------------+--------------+--------------+----------------+
解释:
结果表需包含所有学生和所有科目(即便测试次数为0):
Alice 参加了 3 次数学测试, 2 次物理测试,以及 1 次编程测试;
Bob 参加了 1 次数学测试, 1 次编程测试,没有参加物理测试;
Alex 啥测试都没参加;
John  参加了数学、物理、编程测试各 1 次。

思路:

使用join语句将学生表 (students) 和课程表 (subjects) 进行连接,以获取学生和课程的相关信息。使用left join语句将考试表 (examinations) 与学生、课程表进行左连接,确保即使某些学生没有参加考试,也能包括在结果中。

在on子句中,通过学生ID和课程名进行连接条件的指定,以便获取正确的考试记录。

使用count()函数统计每位学生在每门课程上参加的考试次数,起别名为attended_exams。

使用group by子句按照学生ID和课程名进行分组,以便对每个学生每门课程进行统计。

最后使用order by子句按照学生ID和课程名进行排序,以便输出结果。

代码:

select st.student_id, st.student_name, su.subject_name, count(e.subject_name) as attended_exams
from Students as st
join Subjects as su  -- 连接学生表和课程表
left join Examinations as e  -- 左连接考试表
on st.student_id = e.student_id and e.subject_name = su.subject_name  -- 根据学生ID和课程名进行连接
group by st.student_id, su.subject_name  -- 按学生ID和课程名分组
order by st.student_id, su.subject_name;  -- 按学生ID和课程名排序

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

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

相关文章

Linux学习之Tcp与Udp

目录 UDP Udp协议的格式 UDP的传输特性 UDP的缓冲区 基于UDP的应用层协议 TCP协议 TCP的报文格式 1.ACK确认应答机制 2.超时重传 3.TCP的链接管理机制 为什么要三次握手呢&#xff1f; 理解TIME_WAIT状态 流量控制&#xff08;可靠性效率&#xff09; 滑动窗口 拥塞…

CTFHub-Web-SSRF

CTFHub-Web-SSRF-WP 一、内网访问 1.题目提示说访问127.0.0.1的flag.php&#xff0c;在URL后面添加路径没想到直接访问成功 二、伪协议读取文件 1.题目提示说访问Web目录下的flag.php&#xff0c;联想到Web目录一般存放于/var/www/html/里&#xff0c;去修改URL尝试进行访问…

stm32f103c8t6学习笔记(学习B站up江科大自化协)-UNIX时间戳、BKPRTC

UNIX时间戳 UNIX时间戳最早是在UNIX系统使用的&#xff0c;所以叫做UNIX时间戳&#xff0c;之后很多由UNIX演变而来的系统也继承了UNIX时间戳的规定&#xff0c;目前linux&#xff0c;windows&#xff0c;安卓这些操作系统的底层计时系统都是用UNIX时间戳 时间戳这个计时系统和…

Java对接高德api搜索POI 2.0 关键字搜索

目录 一、注册账号 二、搜索小demo 1.首先要引入依赖 2. 然后查看打印结果即可 三、搜索接口代码 1.引入依赖 2.yml配置 2.Controller 3.静态工具类 四、运行测试 一、注册账号 高德开放平台 | 高德地图API 注册高德开发者&#xff1b;去控制台创建应用&#xff…

Arco design 发布到生成环境F5刷新报错404

问题&#xff1a;开发环境没问题&#xff0c;生成环境正常跳转也没问题但是F5刷新报错 解决办法一&#xff1a;修改 history: createWebHistory(), 改为history: createWebHashHistory(),

在Ubuntu linux操作系统上操作MySQL数据库常用的命令

检查是否安装了MySQL&#xff0c;或检查MySQL的状态&#xff1a; sudo systemctl status mysql或 sudo systemctl status mysql.service如果mysql有安装&#xff0c;上面这条命令会返回mysql的状态active或inactive。 卸载mysql数据库 第一步是停了数据库&#xff1a; sud…

MyBatis 插件介绍及应用

MyBatis 插件介绍及应用 MyBatis 是一个持久层框架&#xff0c;它允许开发者自定义 SQL 语句并将其映射到 Java 对象中。MyBatis 提供了一种灵活的数据库操作方式&#xff0c;但随着项目的复杂度增加&#xff0c;一些通用功能如分页、缓存、事务管理等可能需要重复编写。为了解…

MyBatis(注解方式操作)

文章目录 1.注解方式操作文件目录1.快速入门&#xff08;完整步骤&#xff09;1.pom.xml&#xff08;完整&#xff09;2.resources/jdbc.properties外部配置文件&#xff08;根据实际情况修改参数&#xff09;3.在resources/mybatis-config.xml&#xff08;完整&#xff09;中配…

Android Studio的笔记--布局文件

关于Layout布局文件的使用 LinearLayoutRelativeLayout之前文章的内容一些常见性质在android.graphics.Color中定义了12种常见的颜色常数线性布局LinearLayout 一些常见使用文本框TextView设置文本内容编辑框EditText获取文本内容按钮Button控件使用其他按钮修改图标及名称添加…

智慧旅游驱动行业革新:智能技术引领服务全面升级,匠心打造高品质、个性化旅游新体验

一、引言 随着科技的飞速发展和信息化程度的不断提高&#xff0c;智慧旅游正逐渐成为旅游业发展的新趋势。智慧旅游&#xff0c;顾名思义&#xff0c;是以智能化技术为支撑&#xff0c;通过大数据、云计算、物联网、人工智能等先进技术的应用&#xff0c;实现旅游服务的全面升…

React Router 路由配置数组配组持久化

在一些特定场景下,你可能需要将路由配置数组进行持久化,例如从后端动态加载路由配置或根据用户权限动态生成路由配置。这时,持久化路由配置数组就很有用,可以避免每次应用启动时重新获取或计算路由配置。 持久化路由配置数组的步骤如下: 定义路由配置数组 首先,你需要定义一…

ASR语音转录Prompt优化

ASR语音转录Prompt优化 一、前言 在ASR转录的时候&#xff0c;我们能很明显的感受到有时候语音识别不是很准确&#xff0c;这过程中常见的文本错误主要可以归纳为以下几类&#xff1a; 同音错误&#xff08;Homophone Errors&#xff09; 同音错误发生在不同词语发音相似或相…

使用Postman对@RequestPart和HttpServletRequest组合传参方式

使用Postman对RequestPart和HttpServletRequest组合传参方式 方法代码如下&#xff1a; /*** 发布*/ApiOperation("发布")ApiImplicitParams({ApiImplicitParam(name "req", value "json格式", dataType "Map", dataTypeClass Ma…

【在线名字作画HTML源码】

在线名字作画HTML源码 效果图部分源码领取源码下期更新预报 效果图 部分源码 index.htm <!DOCTYPE html> <html> <head> <title>在线名字作画|民间花鸟字|多彩花鸟虫鱼组合书法|藏字画|字谜语|飞帛板书|意匠文字</title> <meta http-equiv&…

HarmaonyOS鸿蒙应用科普课

一、什么是鸿蒙OS&#xff1f; 1.概念&#xff1a; 先给大家讲讲今天讲课的主题&#xff0c;鸿蒙OS是什么&#xff1f;鸿蒙系统大家都知道&#xff0c;就是一个操作系统&#xff0c;我们未来是为的成为鸿蒙程序员。所以我们不要将鸿蒙os完全等同于手机操作系统&#xff0c;太…

华为 huawei 交换机 配置 MUX VLAN 示例(汇聚层设备)

组网需求 在企业网络中&#xff0c;企业所有员工都可以访问企业的服务器。但对于企业来说&#xff0c;希望企业内部部分员工之间可以互相交流&#xff0c;而部分员工之间是隔离的&#xff0c;不能够互相访问。 如 图 6-4 所示&#xff0c; Switch1 位于网络的汇聚层&#xff0…

Nacos 安全零信任实践

作者&#xff1a;柳遵飞 Nacos 作为配置中心经常存储一些敏感信息&#xff0c;但是由于误用导致安全风险&#xff0c;最常见的主要是以下两个问题&#xff1a; 1&#xff09;Nacos 暴露公网可以吗&#xff1f;不可以&#xff0c;因为 Nacos 定位是注册配置中心&#xff0c;是…

Windows命令行基本命令

目录 什么是相对路径和绝对路径&#xff1f; 一、目录&#xff08;文件夹&#xff09;和文件操作 1.cd命令 用于切换目录 2.dir命令 用于显示目录和文件列表 3.md或mkdir命令 创建文件&#xff0c;也可以创建多级子目录 4.rd命令 用于删除目录 5.move命令 用于移动…

C++:拷贝构造函数和赋值运算符重载

目录 一、拷贝构造函数 1.1概念 1.2特征 二、赋值运算符重载 2.1运算符重载 2.2赋值运算符重载 2.2.1赋值运算符重载格式 2.2.2赋值运算符重载要求 2.2.3默认生成的赋值运算符重载 2.3前置和后置重载 一、拷贝构造函数 1.1概念 只有一个形参&#xff0c;这个形参是…

leetcode51.N皇后(困难)-回溯法

思路 都知道n皇后问题是回溯算法解决的经典问题&#xff0c;但是用回溯解决多了组合、切割、子集、排列问题之后&#xff0c;遇到这种二维矩阵还会有点不知所措。 首先来看一下皇后们的约束条件&#xff1a; 不能同行不能同列不能同斜线 确定完约束条件&#xff0c;来看看究…