练习题(2024/5/6)

1路径总和 II

给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。

叶子节点 是指没有子节点的节点。

示例 1:

输入:root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22
输出:[[5,4,11,2],[5,8,4,5]]

示例 2:

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

示例 3:

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

提示:

  • 树中节点总数在范围 [0, 5000] 内
  • -1000 <= Node.val <= 1000
  • -1000 <= targetSum <= 1000

思路:

.路径总和ii要遍历整个树,找到所有路径,所以递归函数不要返回值

  1. 定义数据结构:首先定义了一个 Solution 类,其中包含了私有成员变量 result 和 path,分别用于存放最终结果和当前路径。

  2. 递归遍历:通过递归方式遍历二叉树的每个节点,从根节点开始向下遍历。递归函数 traversal 的参数包括当前节点指针 cur 和距离目标和还剩余的 count

  3. 叶子节点检查:在递归过程中,如果当前节点是叶子节点且剩余目标和 count 为 0,说明找到了一条满足条件的路径,将该路径添加到结果中。

  4. 路径更新与回溯:在遍历过程中,将经过的节点值添加到 path 数组中,同时更新剩余目标和 count。然后递归遍历左右子树。在递归返回后,需要回溯,即将最后一个节点值移出 path 数组,以便尝试其他路径。

  5. 路径总和函数pathSum 函数是对递归遍历的入口函数,首先清空之前的结果和路径,然后将根节点的值加入初始路径,并调用 traversal 函数开始递归遍历。

代码:

// 定义 Solution 类
class Solution {
private:
    vector<vector<int>> result; // 存放最终结果的二维数组
    vector<int> path; // 存放当前路径的节点值的一维数组
    
    // 递归遍历函数,参数为当前节点指针 cur 和距离目标和还剩余的 count
    void traversal(TreeNode* cur, int count) {
        // 如果当前节点是叶子节点且 count 等于 0,将当前路径添加到结果中
        if (cur->left == nullptr && cur->right == nullptr && count == 0) {
            result.push_back(path);
            return;
        }
        
        // 递归遍历左子树
        if (cur->left) {
            path.push_back(cur->left->val); // 将左子节点值加入路径
            count -= cur->left->val; // 更新剩余目标和
            traversal(cur->left, count); // 递归遍历左子树
            count += cur->left->val; // 恢复剩余目标和
            path.pop_back(); // 移除最后一个节点值,回溯
        }
        
        // 递归遍历右子树
        if (cur->right) {
            path.push_back(cur->right->val); // 将右子节点值加入路径
            count -= cur->right->val; // 更新剩余目标和
            traversal(cur->right, count); // 递归遍历右子树
            count += cur->right->val; // 恢复剩余目标和
            path.pop_back(); // 移除最后一个节点值,回溯
        }
    }

public:
    // 求解路径总和的函数,参数为根节点指针 root 和目标和 targetSum
    vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
        result.clear(); // 清空之前的结果
        path.clear(); // 清空之前的路径
        if (root == nullptr) return result; // 如果根节点为空,直接返回空结果
        
        path.push_back(root->val); // 将根节点的值加入初始路径
        traversal(root, targetSum - root->val); // 调用递归遍历函数
        
        return result; // 返回结果数组
    }
};

2从中序与后序遍历序列构造二叉树

给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。

示例 1:

输入:inorder = [9,3,15,20,7], postorder = [9,15,7,20,3]
输出:[3,9,20,null,null,15,7]

示例 2:

输入:inorder = [-1], postorder = [-1]
输出:[-1]

提示:

  • 1 <= inorder.length <= 3000
  • postorder.length == inorder.length
  • -3000 <= inorder[i], postorder[i] <= 3000
  • inorder 和 postorder 都由 不同 的值组成
  • postorder 中每一个值都在 inorder 中
  • inorder 保证是树的中序遍历
  • postorder 保证是树的后序遍历

思路:

一层一层切割,就应该想到了递归。

一共分以下几步:

  • 如果数组大小为零的话,说明是空节点了。

  • 如果不为空,那么取后序数组最后一个元素作为节点元素。

  • 如果当前节点是叶子节点(后序数组大小为1),直接创建该节点并返回。

  • 找到当前节点在中序遍历数组中的位置,以此位置作为左右子树的分界点。

  • 切割中序遍历数组,得到左子树和右子树的中序数组。

  • 舍弃后序遍历数组末尾元素,因为这个元素作为当前节点。

  • 根据左子树中序数组的大小,切割后序遍历数组,得到左子树和右子树的后序数组。

  • 递归构建左子树和右子树。

  • 将左子树和右子树连接到当前节点的左右孩子上。

代码的解题思路:

  1. 递归函数: traversal 函数是一个递归函数,用于构建二叉树。它接受两个参数:inorder 是中序遍历数组,postorder 是后序遍历数组。

  2. 基准情况: 如果后序遍历数组为空,说明当前子树为空,直接返回空指针。

  3. 根节点: 后序遍历数组的最后一个元素是当前子树的根节点。在每次递归调用中,我们取出后序遍历数组的最后一个元素作为当前子树的根节点,并创建一个 TreeNode 对象。

  4. 叶子节点: 如果后序遍历数组的大小为 1,说明当前节点是叶子节点,直接返回当前节点。

  5. 中序遍历中的根节点位置: 我们在中序遍历数组中找到根节点的位置,以便将中序数组分割为左子树和右子树。

  6. 切割中序数组: 使用根节点在中序遍历数组中的位置来切割中序数组,以得到左子树和右子树的中序遍历数组。

  7. 舍弃后序遍历数组末尾元素: 后序遍历数组的最后一个元素是根节点,所以在递归调用左右子树构建后,我们需要舍弃后序遍历数组的末尾元素,以便构建左右子树。

  8. 切割后序数组: 使用左子树的中序数组的大小来切割后序数组,以得到左子树和右子树的后序遍历数组。

  9. 递归构建左右子树: 分别对左子树和右子树进行递归调用,构建左右子树,并将它们分别连接到当前节点的左右孩子。

  10. 主函数: buildTree 是主函数,用于检查输入数组的有效性,并调用 traversal 函数来构建整个二叉树。

代码: 

class Solution {
private:
    // 定义递归函数,用于构建二叉树
    TreeNode* traversal (vector<int>& inorder, vector<int>& postorder) {
        // 如果后序遍历数组为空,返回空指针
        if (postorder.size() == 0) return NULL;

        // 后序遍历数组最后一个元素,即当前子树的根节点值
        int rootValue = postorder[postorder.size() - 1];
        TreeNode* root = new TreeNode(rootValue);

        // 如果当前节点是叶子节点,直接返回该节点
        if (postorder.size() == 1) return root;

        // 找到当前根节点在中序遍历数组中的位置
        int delimiterIndex;
        for (delimiterIndex = 0; delimiterIndex < inorder.size(); delimiterIndex++) {
            if (inorder[delimiterIndex] == rootValue) break;
        }

        // 切割中序数组,左闭右开区间:[0, delimiterIndex)
        vector<int> leftInorder(inorder.begin(), inorder.begin() + delimiterIndex);
        // [delimiterIndex + 1, end)
        vector<int> rightInorder(inorder.begin() + delimiterIndex + 1, inorder.end() );

        // 舍弃后序遍历数组末尾元素,因为该元素是当前树的根节点
        postorder.resize(postorder.size() - 1);

        // 切割后序数组
        // 依然左闭右开,使用左中序数组大小作为切割点
        // [0, leftInorder.size)
        vector<int> leftPostorder(postorder.begin(), postorder.begin() + leftInorder.size());
        // [leftInorder.size(), end)
        vector<int> rightPostorder(postorder.begin() + leftInorder.size(), postorder.end());

        // 递归构建左右子树
        root->left = traversal(leftInorder, leftPostorder);
        root->right = traversal(rightInorder, rightPostorder);

        return root;
    }
public:
    // 主函数,用于构建二叉树
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        // 如果中序遍历数组或后序遍历数组为空,返回空指针
        if (inorder.size() == 0 || postorder.size() == 0) return NULL;
        // 调用递归函数
        return traversal(inorder, postorder);
    }
};

3合并二叉树

给你两棵二叉树: root1 和 root2 。

想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。你需要将这两棵树合并成一棵新二叉树。合并的规则是:如果两个节点重叠,那么将这两个节点的值相加作为合并后节点的新值;否则,不为 null 的节点将直接作为新二叉树的节点。

返回合并后的二叉树。

注意: 合并过程必须从两个树的根节点开始。

示例 1:

输入:root1 = [1,3,2,5], root2 = [2,1,3,null,4,null,7]
输出:[3,4,5,5,4,null,7]

示例 2:

输入:root1 = [1], root2 = [1,2]
输出:[2,2]

提示:

  • 两棵树中的节点数目在范围 [0, 2000] 内
  • -104 <= Node.val <= 104

思路:

  1. 递归函数: mergeTrees 函数是一个递归函数,用于合并两棵二叉树。它接受两个参数 root1 和 root2,分别表示两棵待合并的二叉树的根节点。

  2. 基准情况: 如果 root1 为空,说明第一棵树为空,直接返回 root2;如果 root2 为空,说明第二棵树为空,直接返回 root1

  3. 递归合并左子树和右子树: 对于当前节点,递归地合并它们的左子树和右子树,分别调用 mergeTrees 函数,将合并后的左子树和右子树连接到当前节点的左孩子和右孩子上。

  4. 合并当前节点的值: 将两棵树当前节点的值相加,并更新到 root1 节点上。

  5. 返回根节点: 返回合并后的第一棵树的根节点 root1

代码:

class Solution {
public:
    // 合并两棵二叉树
    TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
        // 如果第一棵树为空,返回第二棵树
        if (root1 == nullptr) return root2;
        
        // 如果第二棵树为空,返回第一棵树
        if (root2 == nullptr) return root1;
        
        // 递归合并左子树
        root1->left = mergeTrees(root1->left, root2->left);
        // 递归合并右子树
        root1->right = mergeTrees(root1->right, root2->right); // 修正此处的错误
        
        // 合并当前节点的值
        root1->val += root2->val;
        
        // 返回合并后的第一棵树的根节点
        return root1;
    }
};

4按日期分组销售产品

SQL Schema


Pandas Schema


表 Activities

+-------------+---------+
| 列名         | 类型    |
+-------------+---------+
| sell_date   | date    |
| product     | varchar |
+-------------+---------+
该表没有主键(具有唯一值的列)。它可能包含重复项。
此表的每一行都包含产品名称和在市场上销售的日期。

编写解决方案找出每个日期、销售的不同产品的数量及其名称。
每个日期的销售产品名称应按词典序排列。
返回按 sell_date 排序的结果表。
结果表结果格式如下例所示。

示例 1:

输入:
Activities 表:
+------------+-------------+
| sell_date  | product     |
+------------+-------------+
| 2020-05-30 | Headphone   |
| 2020-06-01 | Pencil      |
| 2020-06-02 | Mask        |
| 2020-05-30 | Basketball  |
| 2020-06-01 | Bible       |
| 2020-06-02 | Mask        |
| 2020-05-30 | T-Shirt     |
+------------+-------------+
输出:
+------------+----------+------------------------------+
| sell_date  | num_sold | products                     |
+------------+----------+------------------------------+
| 2020-05-30 | 3        | Basketball,Headphone,T-shirt |
| 2020-06-01 | 2        | Bible,Pencil                 |
| 2020-06-02 | 1        | Mask                         |
+------------+----------+------------------------------+
解释:
对于2020-05-30,出售的物品是 (Headphone, Basketball, T-shirt),按词典序排列,并用逗号 ',' 分隔。
对于2020-06-01,出售的物品是 (Pencil, Bible),按词典序排列,并用逗号分隔。
对于2020-06-02,出售的物品是 (Mask),只需返回该物品名。

思路:

  1. 从 Activities 表中查询销售日期(sell_date)和产品(product)信息。
  2. 使用 count(distinct product) 函数计算每个销售日期下售出的产品的数量,并将结果命名为 num_sold
  3. 使用 group_concat(distinct product order by product asc separator ',') 函数将每个销售日期下售出的产品按照产品名字升序排列,并以逗号分隔合并成一个字段,命名为 products
  4. 使用 group by sell_date 将结果按照销售日期分组。
  5. 使用 order by sell_date 将结果按照销售日期进行升序排序。

group_concat 是一种用于将查询结果集中的多行合并成单行的函数,通常用于将多行数据合并成一行展示。它可以用在 SELECT 查询中,在 GROUP BY 子句的聚合函数中使用。

下面是一个示例用法:

SELECT 
    department_id,
    GROUP_CONCAT(employee_name ORDER BY hire_date SEPARATOR ', ') AS employees
FROM 
    employees
GROUP BY 
    department_id;

 在上面的例子中,假设 employees 表包含了部门ID和雇员名字等信息,通过使用 group_concat 函数按照部门ID分组,将每个部门的雇员名字合并成一行,并按照入职日期排序以逗号分隔显示

代码:

select sell_date,count(distinct product) as num_sold,
group_concat(distinct product order by product asc separator ',')
as products
from Activities
group by sell_date
order by sell_date

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【数据结构】C++语言实现栈(详细解读)

c语言中的小小白-CSDN博客c语言中的小小白关注算法,c,c语言,贪心算法,链表,mysql,动态规划,后端,线性回归,数据结构,排序算法领域.https://blog.csdn.net/bhbcdxb123?spm1001.2014.3001.5343 给大家分享一句我很喜欢我话&#xff1a; 知不足而奋进&#xff0c;望远山而前行&am…

【携程笔试题汇总】[全网首发] 2024-05-06-携程春招笔试题-三语言题解(CPP/Python/Java)

&#x1f36d; 大家好这里是清隆学长 &#xff0c;一枚热爱算法的程序员 ✨ 本系列打算持续跟新携程近期的春秋招笔试题汇总&#xff5e; &#x1f4bb; ACM银牌&#x1f948;| 多次AK大厂笔试 &#xff5c; 编程一对一辅导 &#x1f44f; 感谢大家的订阅➕ 和 喜欢&#x1f49…

【网心云邀请码:KpyV3Dk7】轻松赚油费,新用户专享福利来袭!绑定设备连续在线7 天必得高额奖励

&#x1f4e2; 各位朋友们&#xff0c;好消息来啦&#xff01;现在注册网心云&#xff0c;通过我们的专属邀请码&#xff1a;KpyV3Dk7 &#xff0c;即可享受多重新手福利&#xff0c;让您的闲置设备为您赚钱&#xff01; &#x1f4b8; 立即加入&#xff0c;您将获得&#xff1…

代码本地化

目的 代码本地化&#xff08;Localization&#xff09;是指将软件应用程序中的文本、图形、声音和其他内容翻译成特定语言的过程&#xff0c;同时确保这些内容在目标文化中适当地呈现。本地化不仅仅是对文本进行翻译&#xff0c;还包括对日期、时间、数字、货币、排序顺序、文本…

生成一个好故事!StoryDiffusion:一致自注意力和语义运动预测器必不可少(南开字节)

文章链接&#xff1a;https://arxiv.org/pdf/2405.01434 主页&#xff1a;https://storydiffusion.github.io/ 对于最近基于扩散的生成模型来说&#xff0c;在一系列生成的图像中保持一致的内容&#xff0c;尤其是那些包含主题和复杂细节的图像&#xff0c;是一个重大挑战。本…

C/C++ BM32 合并二叉树

文章目录 前言题目解决方案一1.1 思路阐述1.2 源码 解决方案二2.1 思路阐述2.2 源码 总结 前言 树的题目大概率是要用到递归的&#xff0c;将一个树的问题拆分成子树的问题&#xff0c;不断拆分。 这题也用到了递归的思想。 题目 已知两颗二叉树&#xff0c;将它们合并成一颗…

腾讯地图商业授权说明一篇文章讲清楚如何操作

最近在使用腾讯地图&#xff0c;发现我要上架应用商店APP需要我有地图的授权书。 认真研究了一下原来腾讯地图现在要收费了&#xff0c;如果你打算以商业目的使用它&#xff0c;比如对第三方用户收费或者进行项目投标等&#xff0c;就需要先获取腾讯位置服务的商业授权许可。申…

网络演进技术演进:裸纤专线、SDH、MSTP+、OTN、PTN、IP-RAN

前言 文章主要介绍常见名词以及其在各自领域实现的功能价值。 01 裸纤 裸光纤&#xff08;裸光纤&#xff09;由运营商提供&#xff0c;是无中继的光纤线路&#xff0c;仅通过配线架连接。相比传统光纤&#xff0c;裸光纤提供纯粹的物理传输路径&#xff0c;无需额外网…

win2012磁盘空间不足,c盘正常,d盘无法写入,如何解决?

&#x1f3c6;本文收录于「Bug调优」专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&&…

人工智能概述与入门基础简述

人工智能&#xff08;AI&#xff09;是计算机科学的一个分支&#xff0c;它致力于创建能够执行通常需要人类智能的任务的机器。这篇科普文章将全面介绍人工智能的基本概念、发展历程、主要技术、实际应用以及如何入门这一领域。 一、人工智能的定义与发展历程 人工智能的概念…

vue2实现生成二维码和复制保存图片功能(复制的同时会给图片加文字)

<template><divstyle"display: flex;justify-content: center;align-items: center;width: 100vw;height: 100vh;"><div><!-- 生成二维码按钮和输入二维码的输入框 --><input v-model"url" placeholder"输入链接" ty…

第四篇:记忆的迷宫:探索计算机存储结构的奥秘与创新

记忆的迷宫&#xff1a;探索计算机存储结构的奥秘与创新 1 引言 1.1 计算机存储系统的发展与重要性 在现代计算技术中&#xff0c;存储系统承担着非常关键的角色&#xff0c;它不仅负责信息的持久保存&#xff0c;同时确保高效的数据访问速度&#xff0c;影响着整体系统性能的…

[redis] redis为什么快

1. Redis与Memcached的区别 两者都是非关系型内存键值数据库&#xff0c;现在公司一般都是用 Redis 来实现缓存&#xff0c;而且 Redis 自身也越来越强大了&#xff01;Redis 与 Memcached 主要有以下不同&#xff1a; (1) memcached所有的值均是简单的字符串&#xff0c;red…

electron 通信总结

默认开启上下文隔离的情况下 渲染进程调用主进程方法&#xff1a; 主进程 在 main.js 中&#xff0c; 使用 ipcMain.handle&#xff0c;添加要处理的主进程方法 const { ipcMain } require("electron"); 在 electron 中创建 preload.ts 文件&#xff0c;从 ele…

getchar和putchar函数详解

getchar和putchar函数详解 1.getchar函数1.1函数概述1.2函数返回值1.3函数注意事项1.4函数的使用 2.putchar函数2.1函数概述2.2函数返回值2.3函数使用实例 1.getchar函数 1.1函数概述 从一个流中读取一个字符&#xff0c;或者从标准输入中获得一个字符 函数原型&#xff1a; …

HFSS学习-day1-T形波导的内场分析和优化设计

入门实例--T形波导的内场分析和优化设计 HFSS--此实例详细步骤1.创建项目2.设置求解类型3.设置与建模相关的一些信息设置默认的建模长度单位 4.创建T形模型的三个臂基本参数端口激励进行复制 5.创建被挖去的部分设置正确的边界条件和端口激励方式添加求解设置添加扫频项检查一下…

基于EWT联合SVD去噪

一、代码原理 &#xff08;1&#xff09;基于EWT-SVD的信号去噪算法原理 经验小波变换&#xff08;Empirical Wavelet Transform&#xff0c;EWT&#xff09;&#xff1a;EWT是一种基于信号局部特征的小波变换方法&#xff0c;能够更好地适应非线性和非平稳信号的特性。奇异值…

寻找最佳App分发平台:小猪APP分发脱颖而出

在当今移动应用市场日益饱和的环境下&#xff0c;选择一个合适的App分发平台对于开发者来说至关重要。这不仅关系到应用能否快速触达目标用户&#xff0c;还直接影响到品牌的塑造与市场份额的争夺。本文将深入探讨几大关键因素&#xff0c;帮助开发者判断哪个App分发平台最适合…

pyside6的调色板QPalette的简单应用

使用调色板需要先导入:from PySide6.QtGui import QPalette 调色板QPalette的源代码&#xff1a; class QPalette(Shiboken.Object):class ColorGroup(enum.Enum):Active : QPalette.ColorGroup ... # 0x0Normal : QPalette.ColorGrou…

权益商城系统源码 现支持多种支付方式

简介&#xff1a; 权益商城系统源码&#xff0c;支持多种支付方式&#xff0c;后台商品管理&#xff0c;订单管理&#xff0c;串货管理&#xff0c;分站管理&#xff0c;会员列表&#xff0c;分销日志&#xff0c;应用配置。 上传到服务器&#xff0c;修改数据库信息&#xff…
最新文章