1四数相加 II
给你四个整数数组 nums1
、nums2
、nums3
和 nums4
,数组长度都是 n
,请你计算有多少个元组 (i, j, k, l)
能满足:
0 <= i, j, k, l < n
nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0
示例 1:
输入:nums1 = [1,2], nums2 = [-2,-1], nums3 = [-1,2], nums4 = [0,2] 输出:2 解释: 两个元组如下: 1. (0, 0, 0, 1) -> nums1[0] + nums2[0] + nums3[0] + nums4[1] = 1 + (-2) + (-1) + 2 = 0 2. (1, 1, 0, 0) -> nums1[1] + nums2[1] + nums3[0] + nums4[0] = 2 + (-1) + (-1) + 0 = 0
示例 2:
输入:nums1 = [0], nums2 = [0], nums3 = [0], nums4 = [0] 输出:1
提示:
n == nums1.length
n == nums2.length
n == nums3.length
n == nums4.length
1 <= n <= 200
-228 <= nums1[i], nums2[i], nums3[i], nums4[i] <= 228
思路:
-
初始化哈希表: 创建一个哈希表
map
,用于存储 nums1 和 nums2 中所有数的和及其出现次数。 -
计算和及其出现次数: 遍历 nums1 和 nums2 中的所有数,计算它们的和,并更新哈希表中对应和的出现次数。
-
查找相加为零的数对: 遍历 nums3 和 nums4 中的所有数,查找它们的和是否在哈希表中存在相反数。如果存在,则将对应和的出现次数加入计数器中。
-
返回结果: 返回计数器中的值,即满足条件的数对数目。
代码:
class Solution {
public:int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {// 哈希表用于存储两个数组中元素之和及其出现次数unordered_map<int, int> map;// 计算 nums1 和 nums2 中所有数的和及其出现次数for (int num1 : nums1) {for (int num2 : nums2) {// 更新哈希表中对应和的出现次数map[num1 + num2]++;}}// 初始化计数器int count = 0;// 遍历 nums3 和 nums4 中所有数,查找是否存在相加为零的数对for (int num3 : nums3) {for (int num4 : nums4) {// 判断是否存在相反数在哈希表中if (map.find(0 - (num3 + num4)) != map.end()) {// 更新计数器count += map[0 - (num3 + num4)];}}}// 返回计数器中的值,即满足条件的数对数目return count;}
};
2每位经理的下属员工数量
表:Employees
+-------------+----------+ | Column Name | Type | +-------------+----------+ | employee_id | int | | name | varchar | | reports_to | int | | age | int | +-------------+----------+ employee_id 是这个表中具有不同值的列。 该表包含员工以及需要听取他们汇报的上级经理的 ID 的信息。 有些员工不需要向任何人汇报(reports_to 为空)。
对于此问题,我们将至少有一个其他员工需要向他汇报的员工,视为一个经理。
编写一个解决方案来返回需要听取汇报的所有经理的 ID、名称、直接向该经理汇报的员工人数,以及这些员工的平均年龄,其中该平均年龄需要四舍五入到最接近的整数。
返回的结果集需要按照 employee_id
进行排序。
结果的格式如下:
示例 1:
输入: Employees 表: +-------------+---------+------------+-----+ | employee_id | name | reports_to | age | +-------------+---------+------------+-----+ | 9 | Hercy | null | 43 | | 6 | Alice | 9 | 41 | | 4 | Bob | 9 | 36 | | 2 | Winston | null | 37 | +-------------+---------+------------+-----+ 输出: +-------------+-------+---------------+-------------+ | employee_id | name | reports_count | average_age | +-------------+-------+---------------+-------------+ | 9 | Hercy | 2 | 39 | +-------------+-------+---------------+-------------+ 解释: Hercy 有两个需要向他汇报的员工, 他们是 Alice and Bob. 他们的平均年龄是 (41+36)/2 = 38.5, 四舍五入的结果是 39.
示例 2:
输入: Employees 表: +-------------+---------+------------+-----+ | employee_id | name | reports_to | age | |-------------|---------|------------|-----| | 1 | Michael | null | 45 | | 2 | Alice | 1 | 38 | | 3 | Bob | 1 | 42 | | 4 | Charlie | 2 | 34 | | 5 | David | 2 | 40 | | 6 | Eve | 3 | 37 | | 7 | Frank | null | 50 | | 8 | Grace | null | 48 | +-------------+---------+------------+-----+ 输出: +-------------+---------+---------------+-------------+ | employee_id | name | reports_count | average_age | | ----------- | ------- | ------------- | ----------- | | 1 | Michael | 2 | 40 | | 2 | Alice | 2 | 37 | | 3 | Bob | 1 | 37 | +-------------+---------+---------------+-------------+
思路:
-
连接表: 使用 inner i join将 Employees 表自连接,连接条件是员工的 employee_id 等于其直接上级的 reports_to。
-
计算直接下属数量和平均年龄: 使用 count函数计算每个员工的直接下属数量,并使用 avg 函数计算直接下属的平均年龄。
-
分组和排序: 使用 GROUP BY 子句按照员工编号分组,然后使用 ORDER BY 子句按照员工编号进行排序。
代码:
sql">select a.employee_id as 'employee_id', a.name as 'name', count(b.employee_id) as 'reports_count', round(avg(b.age), 0) as 'average_age'
from Employees a inner join Employees b on a.employee_id = b.reports_to
group by a.employee_id
order by a.employee_id;
3查找每个员工花费的总时间
表: Employees
+-------------+------+ | Column Name | Type | +-------------+------+ | emp_id | int | | event_day | date | | in_time | int | | out_time | int | +-------------+------+ 在 SQL 中,(emp_id, event_day, in_time) 是这个表的主键。 该表显示了员工在办公室的出入情况。 event_day 是此事件发生的日期,in_time 是员工进入办公室的时间,而 out_time 是他们离开办公室的时间。 in_time 和 out_time 的取值在1到1440之间。 题目保证同一天没有两个事件在时间上是相交的,并且保证 in_time 小于 out_time。
计算每位员工每天在办公室花费的总时间(以分钟为单位)。 请注意,在一天之内,同一员工是可以多次进入和离开办公室的。 在办公室里一次进出所花费的时间为out_time 减去 in_time。
返回结果表单的顺序无要求。
查询结果的格式如下:
示例 1:
输入: Employees table: +--------+------------+---------+----------+ | emp_id | event_day | in_time | out_time | +--------+------------+---------+----------+ | 1 | 2020-11-28 | 4 | 32 | | 1 | 2020-11-28 | 55 | 200 | | 1 | 2020-12-03 | 1 | 42 | | 2 | 2020-11-28 | 3 | 33 | | 2 | 2020-12-09 | 47 | 74 | +--------+------------+---------+----------+ 输出: +------------+--------+------------+ | day | emp_id | total_time | +------------+--------+------------+ | 2020-11-28 | 1 | 173 | | 2020-11-28 | 2 | 30 | | 2020-12-03 | 1 | 41 | | 2020-12-09 | 2 | 27 | +------------+--------+------------+ 解释: 雇员 1 有三次进出: 有两次发生在 2020-11-28 花费的时间为 (32 - 4) + (200 - 55) = 173, 有一次发生在 2020-12-03 花费的时间为 (42 - 1) = 41。 雇员 2 有两次进出: 有一次发生在 2020-11-28 花费的时间为 (33 - 3) = 30, 有一次发生在 2020-12-09 花费的时间为 (74 - 47) = 27。
思路:
-
选择字段: 选择查询结果需要显示的字段,包括事件日期(event_day)、员工编号(emp_id)以及员工的总工作时长(total_time)。
-
计算总工作时长: 使用 SUM 函数计算每位员工在每个事件日期的总工作时长,这通过计算 out_time 减去 in_time 得到。
-
分组: 使用 GROUP BY 子句将数据按照事件日期(event_day)和员工编号(emp_id)分组,以便对每位员工在每日的工作时长进行统计。
代码:
sql">select event_day as day, emp_id, sum(out_time - in_time) as total_time
from Employees
group by event_day, emp_id;
4可回收且低脂的产品
表:Products
+-------------+---------+
| Column Name | Type |
+-------------+---------+
| product_id | int |
| low_fats | enum |
| recyclable | enum |
+-------------+---------+
product_id
是该表的主键(具有唯一值的列)。
low_fats 是枚举类型,取值为以下两种 ('Y', 'N'),其中 'Y' 表示该产品是低脂产品,'N' 表示不是低脂产品。
recyclable 是枚举类型,取值为以下两种 ('Y', 'N'),其中 'Y' 表示该产品可回收,而 'N' 表示不可回收。
编写解决方案找出既是低脂又是可回收的产品编号。
返回结果 无顺序要求 。
返回结果格式如下例所示:
示例 1:
输入: Products 表: +-------------+----------+------------+ | product_id | low_fats | recyclable | +-------------+----------+------------+ | 0 | Y | N | | 1 | Y | Y | | 2 | N | Y | | 3 | Y | Y | | 4 | N | N | +-------------+----------+------------+ 输出: +-------------+ | product_id | +-------------+ | 1 | | 3 | +-------------+ 解释: 只有产品 id 为 1 和 3 的产品,既是低脂又是可回收的产品。
代码:
sql">selectproduct_id
fromProducts
wherelow_fats = 'Y' and recyclable = 'Y'