练习题(2024/5/3)

1对称二叉树

给你一个二叉树的根节点 root , 检查它是否轴对称。

示例 1:

复制代码
输入:root = [1,2,2,3,4,4,3]
输出:true

示例 2:

复制代码
输入:root = [1,2,2,null,3,null,3]
输出:false

提示:

  • 树中节点数目在范围 [1, 1000]
  • -100 <= Node.val <= 100

递归思路:

  1. 定义递归的函数功能:
    • 比较左右子树是否对称
  2. 确定递归的结束条件:
    • 当左节点和右节点都为空时,说明对称,返回true
    • 当左节点和右节点其中一个为空时,说明不对称,返回false
    • 当左节点和右节点的数值不相等时,说明不对称,返回false
  3. 确定递归的返回值:
    • 返回左子树的左节点和右子树的右节点是否对称,以及左子树的右节点和右子树的左节点是否对称,两者都对称则返回true,否则返回false
  4. 在主函数中调用递归函数,判断整棵树是否对称。如果根节点为空,直接返回true;否则调用递归函数进行判断。

代码:

cpp 复制代码
class Solution {
public:
    // 递归函数,用于比较左右子树是否对称
    bool compare(TreeNode* left, TreeNode* right) {
        // 首先排除空节点的情况
        if (left == NULL && right != NULL) return false;
        else if (left != NULL && right == NULL) return false;
        else if (left == NULL && right == NULL) return true;
        // 排除了空节点,再排除数值不相同的情况
        else if (left->val != right->val) return false;

        // 此时左右节点都不为空,且数值相同的情况,继续递归判断子树
        bool outside = compare(left->left, right->right);   // 左子树的左节点和右子树的右节点比较
        bool inside = compare(left->right, right->left);    // 左子树的右节点和右子树的左节点比较
        bool isSame = outside && inside;                    // 判断是否对称
        return isSame;                                      // 返回结果
    }

    // 主函数,判断整棵树是否对称
    bool isSymmetric(TreeNode* root) {
        if (root == NULL) return true;      // 空树也算对称
        return compare(root->left, root->right);  // 调用递归函数比较左右子树
    }
};

2完全二叉树的节点个数

给你一棵完全二叉树 的根节点 root ,求出该树的节点个数。

完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2h 个节点。

示例 1:

复制代码
输入:root = [1,2,3,4,5,6]
输出:6

示例 2:

复制代码
输入:root = []
输出:0

示例 3:

复制代码
输入:root = [1]
输出:1

提示:

  • 树中节点的数目范围是[0, 5 * 104]
  • 0 <= Node.val <= 5 * 104
  • 题目数据保证输入的树是 完全二叉树

思路:

通过递归的方式计算一棵树的节点数。在递归函数中,先判断当前节点是否为空,若为空则节点数为0;然后递归计算左右子树的节点数,并将左右子树节点数之和加上当前节点即为当前子树的节点数。主函数调用递归函数计算整棵树的节点数,并返回结果。

代码:

cpp 复制代码
class Solution {
private:
    // 递归函数,用于获取以当前节点为根的子树的节点数
    int getNodesNum(TreeNode* cur) {
        // 当前节点为空,节点数为0
        if (cur == nullptr) return 0;
        
        // 递归获取左子树节点数
        int leftNum = getNodesNum(cur->left);      // 左
        // 递归获取右子树节点数
        int rightNum = getNodesNum(cur->right);    // 右
        // 当前节点的节点数为左右子树节点数之和加上当前节点
        int treeNum = leftNum + rightNum + 1;      // 中
        
        return treeNum;
    }
public:
    // 主函数,计算整棵树的节点数
    int countNodes(TreeNode* root) {
        // 调用递归函数获取整棵树的节点数
        return getNodesNum(root);
    }
};

2迭代思路:

使用了队列来按层遍历整棵树,并统计节点的数量。首先将根节点压入队列,然后进入循环,每次循环先获取当前层节点的数量,然后对当前层节点进行遍历,依次取出节点,统计节点数量,并将节点的左右子节点(如果存在)压入队列。最终返回统计的节点数量。

代码:

cpp 复制代码
class Solution{
    public:
      int countNodes(TreeNode* root){
        queue<TreeNode* > que; // 定义一个队列用于存储节点
        if(root !=nullptr)  que.push(root); // 将根节点压入队列
        int result =0; // 记录节点数量
        while(!que.empty()){ // 循环直到队列为空
            int size=que.size(); // 获取当前队列大小,即当前层节点数量
            for(int i=0;i<size;i++){ // 对当前层节点进行遍历
                TreeNode* node=que.front(); // 取出队首节点
                que.pop(); // 弹出队首节点
                result++;   // 记录节点数量
                if (node->left) que.push(node->left); // 左子树不为空则压入队列
                if (node->right) que.push(node->right); // 右子树不为空则压入队列
            }
        }
        return result; // 返回节点数量
      }
};

3平衡二叉树

给定一个二叉树,判断它是否是

平衡二叉树

平衡二叉树 是指该树所有节点的左右子树的深度相差不超过 1。

示例 1:

复制代码
输入:root = [3,9,20,null,null,15,7]
输出:true

示例 2:

复制代码
输入:root = [1,2,2,3,3,null,null,4,4]
输出:false

示例 3:

复制代码
输入:root = []
输出:true

思路:

通过递归的方式来判断一个二叉树是否是平衡二叉树。其中getHeight函数用来计算以当前节点为根节点的二叉树的高度,如果不是平衡二叉树则返回-1。在计算当前节点的高度时,先递归计算左子树和右子树的高度,如果左子树或右子树不是平衡二叉树(高度为-1),则直接返回-1。然后再判断左右子树的高度差是否大于1,如果是则返回-1,否则返回当前节点为根节点的二叉树的高度。最后在isBalanced函数中判断整棵树的高度是否为-1,如果是则返回false,否则返回true

代码:

cpp 复制代码
class Solution {
public:
    // 返回以该节点为根节点的二叉树的高度,如果不是平衡二叉树则返回-1
    int getHeight(TreeNode* node) {
        if (node == NULL) {
            return 0; // 如果节点为空,返回高度0
        }
        int leftHeight = getHeight(node->left); // 获取左子树的高度
        if (leftHeight == -1) {
            return -1; // 如果左子树不是平衡二叉树,直接返回-1
        }
        int rightHeight = getHeight(node->right); // 获取右子树的高度
        if (rightHeight == -1) {
            return -1; // 如果右子树不是平衡二叉树,直接返回-1
        }
        if (abs(leftHeight - rightHeight) > 1) { // 如果左右子树高度差大于1,则不是平衡二叉树
            return -1;
        } else {
            return 1 + max(leftHeight, rightHeight); // 返回当前节点为根节点的二叉树的高度
        }
    }
    bool isBalanced(TreeNode* root) {
        int height = getHeight(root); // 获取二叉树的高度
        if (height == -1) {
            return false; // 如果高度为-1,则不是平衡二叉树
        } else {
            return true; // 否则是平衡二叉树
        }
    }
};

4使用唯一标识码替换员工ID

Employees 表:

复制代码
+---------------+---------+
| Column Name   | Type    |
+---------------+---------+
| id            | int     |
| name          | varchar |
+---------------+---------+
在 SQL 中,id 是这张表的主键。
这张表的每一行分别代表了某公司其中一位员工的名字和 ID 。

EmployeeUNI 表:

复制代码
+---------------+---------+
| Column Name   | Type    |
+---------------+---------+
| id            | int     |
| unique_id     | int     |
+---------------+---------+
在 SQL 中,(id, unique_id) 是这张表的主键。
这张表的每一行包含了该公司某位员工的 ID 和他的唯一标识码(unique ID)。

展示每位用户的唯一标识码(unique ID );如果某位员工没有唯一标识码,使用 null 填充即可。

你可以以任意 顺序返回结果表。

返回结果的格式如下例所示。

示例 1:

输入:
Employees 表:
+----+----------+
| id | name     |
+----+----------+
| 1  | Alice    |
| 7  | Bob      |
| 11 | Meir     |
| 90 | Winston  |
| 3  | Jonathan |
+----+----------+
EmployeeUNI 表:
+----+-----------+
| id | unique_id |
+----+-----------+
| 3  | 1         |
| 11 | 2         |
| 90 | 3         |
+----+-----------+
输出:
+-----------+----------+
| unique_id | name     |
+-----------+----------+
| null      | Alice    |
| null      | Bob      |
| 2         | Meir     |
| 3         | Winston  |
| 1         | Jonathan |
+-----------+----------+
解释:
Alice and Bob 没有唯一标识码, 因此我们使用 null 替代。
Meir 的唯一标识码是 2 。
Winston 的唯一标识码是 3 。
Jonathan 唯一标识码是 1 。

思路:

通过左连接(left join)将两个表Employees和EmployeeUNI进行关联查询,关联条件是Employees表中的id字段与EmployeeUNI表中的id字段相等。查询结果包括了EmployeeUNI表中的unique_id字段和Employees表中的name字段,以展示每位员工的唯一身份ID和姓名。

代码:

sql 复制代码
select
    EmployeeUNI.unique_id, Employees.name
from 
    Employees
left join
    EmployeeUNI
on
    Employees.id = EmployeeUNI.id
相关推荐
爱吃生蚝的于勒1 小时前
C语言内存函数
c语言·开发语言·数据结构·c++·学习·算法
ChoSeitaku7 小时前
链表循环及差集相关算法题|判断循环双链表是否对称|两循环单链表合并成循环链表|使双向循环链表有序|单循环链表改双向循环链表|两链表的差集(C)
c语言·算法·链表
DdddJMs__1357 小时前
C语言 | Leetcode C语言题解之第557题反转字符串中的单词III
c语言·leetcode·题解
Fuxiao___7 小时前
不使用递归的决策树生成算法
算法
我爱工作&工作love我7 小时前
1435:【例题3】曲线 一本通 代替三分
c++·算法
白-胖-子7 小时前
【蓝桥等考C++真题】蓝桥杯等级考试C++组第13级L13真题原题(含答案)-统计数字
开发语言·c++·算法·蓝桥杯·等考·13级
workflower7 小时前
数据结构练习题和答案
数据结构·算法·链表·线性回归
好睡凯7 小时前
c++写一个死锁并且自己解锁
开发语言·c++·算法
Sunyanhui18 小时前
力扣 二叉树的直径-543
算法·leetcode·职场和发展
一个不喜欢and不会代码的码农8 小时前
力扣105:从先序和中序序列构造二叉树
数据结构·算法·leetcode