diff --git a/solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/README.md b/solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/README.md index b7dc7b03596aa..907de5036c28b 100644 --- a/solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/README.md +++ b/solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/README.md @@ -314,7 +314,7 @@ function getDirections(root: TreeNode | null, startValue: number, destValue: num const left = lca(node.left, p, q); const right = lca(node.right, p, q); - return left && right ? node : left ?? right; + return left && right ? node : (left ?? right); }; const dfs = (node: TreeNode | null, x: number, path: string[]): boolean => { @@ -370,7 +370,7 @@ var getDirections = function (root, startValue, destValue) { const left = lca(node.left, p, q); const right = lca(node.right, p, q); - return left && right ? node : left ?? right; + return left && right ? node : (left ?? right); }; const dfs = (node, x, path) => { diff --git a/solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/README_EN.md b/solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/README_EN.md index 41a9811d4e980..58782483df639 100644 --- a/solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/README_EN.md +++ b/solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/README_EN.md @@ -310,7 +310,7 @@ function getDirections(root: TreeNode | null, startValue: number, destValue: num const left = lca(node.left, p, q); const right = lca(node.right, p, q); - return left && right ? node : left ?? right; + return left && right ? node : (left ?? right); }; const dfs = (node: TreeNode | null, x: number, path: string[]): boolean => { @@ -366,7 +366,7 @@ var getDirections = function (root, startValue, destValue) { const left = lca(node.left, p, q); const right = lca(node.right, p, q); - return left && right ? node : left ?? right; + return left && right ? node : (left ?? right); }; const dfs = (node, x, path) => { diff --git a/solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/Solution.js b/solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/Solution.js index c6ca93d60610d..cf11074f0553b 100644 --- a/solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/Solution.js +++ b/solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/Solution.js @@ -20,7 +20,7 @@ var getDirections = function (root, startValue, destValue) { const left = lca(node.left, p, q); const right = lca(node.right, p, q); - return left && right ? node : left ?? right; + return left && right ? node : (left ?? right); }; const dfs = (node, x, path) => { diff --git a/solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/Solution.ts b/solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/Solution.ts index fa2f24e5d72b9..5c028830da797 100644 --- a/solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/Solution.ts +++ b/solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/Solution.ts @@ -20,7 +20,7 @@ function getDirections(root: TreeNode | null, startValue: number, destValue: num const left = lca(node.left, p, q); const right = lca(node.right, p, q); - return left && right ? node : left ?? right; + return left && right ? node : (left ?? right); }; const dfs = (node: TreeNode | null, x: number, path: string[]): boolean => { diff --git a/solution/2200-2299/2205.The Number of Users That Are Eligible for Discount/README.md b/solution/2200-2299/2205.The Number of Users That Are Eligible for Discount/README.md index 6854118c4541a..6631f19ba30cd 100644 --- a/solution/2200-2299/2205.The Number of Users That Are Eligible for Discount/README.md +++ b/solution/2200-2299/2205.The Number of Users That Are Eligible for Discount/README.md @@ -66,6 +66,10 @@ startDate = 2022-03-08, endDate = 2022-03-20, minAmount = 1000 - 用户 2 在时间间隔内有一次购买,但金额小于 minAmount。 - 用户 3 是唯一一个购买行为同时满足这两个条件的用户。 +

 

+ +

重要提示:此问题与 2230. 查找可享受优惠的用户 基本相同。

+ ## 解法 diff --git a/solution/3200-3299/3278.Find Candidates for Data Scientist Position II/README.md b/solution/3200-3299/3278.Find Candidates for Data Scientist Position II/README.md new file mode 100644 index 0000000000000..c8fcb9c764b8e --- /dev/null +++ b/solution/3200-3299/3278.Find Candidates for Data Scientist Position II/README.md @@ -0,0 +1,197 @@ +--- +comments: true +difficulty: 中等 +edit_url: https://github.com/doocs/leetcode/edit/main/solution/3200-3299/3278.Find%20Candidates%20for%20Data%20Scientist%20Position%20II/README.md +tags: + - 数据库 +--- + + + +# [3278. Find Candidates for Data Scientist Position II 🔒](https://leetcode.cn/problems/find-candidates-for-data-scientist-position-ii) + +[English Version](/solution/3200-3299/3278.Find%20Candidates%20for%20Data%20Scientist%20Position%20II/README_EN.md) + +## 题目描述 + + + +

Table: Candidates

+ +
++--------------+---------+ 
+| Column Name  | Type    | 
++--------------+---------+ 
+| candidate_id | int     | 
+| skill        | varchar |
+| proficiency  | int     |
++--------------+---------+
+(candidate_id, skill) is the unique key for this table.
+Each row includes candidate_id, skill, and proficiency level (1-5).
+
+ +

Table: Projects

+ +
++--------------+---------+ 
+| Column Name  | Type    | 
++--------------+---------+ 
+| project_id   | int     | 
+| skill        | varchar |
+| importance   | int     |
++--------------+---------+
+(project_id, skill) is the primary key for this table.
+Each row includes project_id, required skill, and its importance (1-5) for the project.
+
+ +

Leetcode is staffing for multiple data science projects. Write a solution to find the best candidate for each project based on the following criteria:

+ +
    +
  1. Candidates must have all the skills required for a project.
  2. +
  3. Calculate a score for each candidate-project pair as follows: + +
  4. +
+ +

Include only the top candidate (highest score) for each project. If there’s a tie, choose the candidate with the lower candidate_id. If there is no suitable candidate for a project, do not return that project.

+ +

Return a result table ordered by project_id in ascending order.

+ +

The result format is in the following example.

+ +

 

+

Example:

+ +
+

Input:

+ +

Candidates table:

+ +
++--------------+-----------+-------------+
+| candidate_id | skill     | proficiency |
++--------------+-----------+-------------+
+| 101          | Python    | 5           |
+| 101          | Tableau   | 3           |
+| 101          | PostgreSQL| 4           |
+| 101          | TensorFlow| 2           |
+| 102          | Python    | 4           |
+| 102          | Tableau   | 5           |
+| 102          | PostgreSQL| 4           |
+| 102          | R         | 4           |
+| 103          | Python    | 3           |
+| 103          | Tableau   | 5           |
+| 103          | PostgreSQL| 5           |
+| 103          | Spark     | 4           |
++--------------+-----------+-------------+
+
+ +

Projects table:

+ +
++-------------+-----------+------------+
+| project_id  | skill     | importance |
++-------------+-----------+------------+
+| 501         | Python    | 4          |
+| 501         | Tableau   | 3          |
+| 501         | PostgreSQL| 5          |
+| 502         | Python    | 3          |
+| 502         | Tableau   | 4          |
+| 502         | R         | 2          |
++-------------+-----------+------------+
+
+ +

Output:

+ +
++-------------+--------------+-------+
+| project_id  | candidate_id | score |
++-------------+--------------+-------+
+| 501         | 101          | 105   |
+| 502         | 102          | 130   |
++-------------+--------------+-------+
+
+ +

Explanation:

+ + + +

The output table is ordered by project_id in ascending order.

+
+ + + +## 解法 + + + +### 方法一:等值连接 + 分组统计 + 窗口函数 + +我们可以将表 `Candidates` 和表 `Projects` 通过 `skill` 列进行等值连接,统计每个候选人在每个项目中匹配的技能数量、总分数,记录在表 `S` 中。 + +然后我们再次统计每个项目所需的技能数量,记录在表 `T` 中。 + +接着我们将表 `S` 和表 `T` 通过 `project_id` 列进行等值连接,筛选出匹配的技能数量等于所需技能数量的候选人,记录在表 `P` 中,并计算每个项目的候选人排名,字段为 `rk`。 + +最后我们筛选出每个项目的排名为 1 的候选人,即为最佳候选人。 + + + +#### MySQL + +```sql +WITH + S AS ( + SELECT + candidate_id, + project_id, + COUNT(*) matched_skills, + SUM( + CASE + WHEN proficiency > importance THEN 10 + WHEN proficiency < importance THEN -5 + ELSE 0 + END + ) + 100 AS score + FROM + Candidates + JOIN Projects USING (skill) + GROUP BY 1, 2 + ), + T AS ( + SELECT project_id, COUNT(1) required_skills + FROM Projects + GROUP BY 1 + ), + P AS ( + SELECT + project_id, + candidate_id, + score, + RANK() OVER ( + PARTITION BY project_id + ORDER BY score DESC, candidate_id + ) rk + FROM + S + JOIN T USING (project_id) + WHERE matched_skills = required_skills + ) +SELECT project_id, candidate_id, score +FROM P +WHERE rk = 1 +ORDER BY 1; +``` + + + + + + diff --git a/solution/3200-3299/3278.Find Candidates for Data Scientist Position II/README_EN.md b/solution/3200-3299/3278.Find Candidates for Data Scientist Position II/README_EN.md new file mode 100644 index 0000000000000..d12ce33590cf9 --- /dev/null +++ b/solution/3200-3299/3278.Find Candidates for Data Scientist Position II/README_EN.md @@ -0,0 +1,197 @@ +--- +comments: true +difficulty: Medium +edit_url: https://github.com/doocs/leetcode/edit/main/solution/3200-3299/3278.Find%20Candidates%20for%20Data%20Scientist%20Position%20II/README_EN.md +tags: + - Database +--- + + + +# [3278. Find Candidates for Data Scientist Position II 🔒](https://leetcode.com/problems/find-candidates-for-data-scientist-position-ii) + +[中文文档](/solution/3200-3299/3278.Find%20Candidates%20for%20Data%20Scientist%20Position%20II/README.md) + +## Description + + + +

Table: Candidates

+ +
++--------------+---------+ 
+| Column Name  | Type    | 
++--------------+---------+ 
+| candidate_id | int     | 
+| skill        | varchar |
+| proficiency  | int     |
++--------------+---------+
+(candidate_id, skill) is the unique key for this table.
+Each row includes candidate_id, skill, and proficiency level (1-5).
+
+ +

Table: Projects

+ +
++--------------+---------+ 
+| Column Name  | Type    | 
++--------------+---------+ 
+| project_id   | int     | 
+| skill        | varchar |
+| importance   | int     |
++--------------+---------+
+(project_id, skill) is the primary key for this table.
+Each row includes project_id, required skill, and its importance (1-5) for the project.
+
+ +

Leetcode is staffing for multiple data science projects. Write a solution to find the best candidate for each project based on the following criteria:

+ +
    +
  1. Candidates must have all the skills required for a project.
  2. +
  3. Calculate a score for each candidate-project pair as follows: + +
  4. +
+ +

Include only the top candidate (highest score) for each project. If there’s a tie, choose the candidate with the lower candidate_id. If there is no suitable candidate for a project, do not return that project.

+ +

Return a result table ordered by project_id in ascending order.

+ +

The result format is in the following example.

+ +

 

+

Example:

+ +
+

Input:

+ +

Candidates table:

+ +
++--------------+-----------+-------------+
+| candidate_id | skill     | proficiency |
++--------------+-----------+-------------+
+| 101          | Python    | 5           |
+| 101          | Tableau   | 3           |
+| 101          | PostgreSQL| 4           |
+| 101          | TensorFlow| 2           |
+| 102          | Python    | 4           |
+| 102          | Tableau   | 5           |
+| 102          | PostgreSQL| 4           |
+| 102          | R         | 4           |
+| 103          | Python    | 3           |
+| 103          | Tableau   | 5           |
+| 103          | PostgreSQL| 5           |
+| 103          | Spark     | 4           |
++--------------+-----------+-------------+
+
+ +

Projects table:

+ +
++-------------+-----------+------------+
+| project_id  | skill     | importance |
++-------------+-----------+------------+
+| 501         | Python    | 4          |
+| 501         | Tableau   | 3          |
+| 501         | PostgreSQL| 5          |
+| 502         | Python    | 3          |
+| 502         | Tableau   | 4          |
+| 502         | R         | 2          |
++-------------+-----------+------------+
+
+ +

Output:

+ +
++-------------+--------------+-------+
+| project_id  | candidate_id | score |
++-------------+--------------+-------+
+| 501         | 101          | 105   |
+| 502         | 102          | 130   |
++-------------+--------------+-------+
+
+ +

Explanation:

+ + + +

The output table is ordered by project_id in ascending order.

+
+ + + +## Solutions + + + +### Solution 1: Equi-Join + Group Statistics + Window Function + +We can perform an equi-join of the `Candidates` table and the `Projects` table on the `skill` column, counting the number of matched skills and calculating the total score for each candidate in each project, which is recorded in table `S`. + +Next, we count the required number of skills for each project, recording the results in table `T`. + +Then, we perform an equi-join of tables `S` and `T` on the `project_id` column, filtering out candidates whose number of matched skills equals the required number of skills, and recording them in table `P`. We calculate the rank (`rk`) for each candidate within each project. + +Finally, we filter out the candidates with rank $rk = 1$ for each project, identifying them as the best candidates. + + + +#### MySQL + +```sql +WITH + S AS ( + SELECT + candidate_id, + project_id, + COUNT(*) matched_skills, + SUM( + CASE + WHEN proficiency > importance THEN 10 + WHEN proficiency < importance THEN -5 + ELSE 0 + END + ) + 100 AS score + FROM + Candidates + JOIN Projects USING (skill) + GROUP BY 1, 2 + ), + T AS ( + SELECT project_id, COUNT(1) required_skills + FROM Projects + GROUP BY 1 + ), + P AS ( + SELECT + project_id, + candidate_id, + score, + RANK() OVER ( + PARTITION BY project_id + ORDER BY score DESC, candidate_id + ) rk + FROM + S + JOIN T USING (project_id) + WHERE matched_skills = required_skills + ) +SELECT project_id, candidate_id, score +FROM P +WHERE rk = 1 +ORDER BY 1; +``` + + + + + + diff --git a/solution/3200-3299/3278.Find Candidates for Data Scientist Position II/Solution.sql b/solution/3200-3299/3278.Find Candidates for Data Scientist Position II/Solution.sql new file mode 100644 index 0000000000000..aae9bea90b147 --- /dev/null +++ b/solution/3200-3299/3278.Find Candidates for Data Scientist Position II/Solution.sql @@ -0,0 +1,41 @@ +WITH + S AS ( + SELECT + candidate_id, + project_id, + COUNT(*) matched_skills, + SUM( + CASE + WHEN proficiency > importance THEN 10 + WHEN proficiency < importance THEN -5 + ELSE 0 + END + ) + 100 AS score + FROM + Candidates + JOIN Projects USING (skill) + GROUP BY 1, 2 + ), + T AS ( + SELECT project_id, COUNT(1) required_skills + FROM Projects + GROUP BY 1 + ), + P AS ( + SELECT + project_id, + candidate_id, + score, + RANK() OVER ( + PARTITION BY project_id + ORDER BY score DESC, candidate_id + ) rk + FROM + S + JOIN T USING (project_id) + WHERE matched_skills = required_skills + ) +SELECT project_id, candidate_id, score +FROM P +WHERE rk = 1 +ORDER BY 1; diff --git a/solution/DATABASE_README.md b/solution/DATABASE_README.md index 383c7b7f434bc..ad5c9bcac912f 100644 --- a/solution/DATABASE_README.md +++ b/solution/DATABASE_README.md @@ -294,6 +294,7 @@ | 3252 | [英超积分榜排名 II](/solution/3200-3299/3252.Premier%20League%20Table%20Ranking%20II/README.md) | `数据库` | 中等 | 🔒 | | 3262 | [查找重叠的班次](/solution/3200-3299/3262.Find%20Overlapping%20Shifts/README.md) | `数据库` | 中等 | 🔒 | | 3268 | [查找重叠的班次 II](/solution/3200-3299/3268.Find%20Overlapping%20Shifts%20II/README.md) | `数据库` | 困难 | 🔒 | +| 3278 | [Find Candidates for Data Scientist Position II](/solution/3200-3299/3278.Find%20Candidates%20for%20Data%20Scientist%20Position%20II/README.md) | | 中等 | 🔒 | ## 版权 diff --git a/solution/DATABASE_README_EN.md b/solution/DATABASE_README_EN.md index 74fa25d81f661..a8d4451223a4f 100644 --- a/solution/DATABASE_README_EN.md +++ b/solution/DATABASE_README_EN.md @@ -292,6 +292,7 @@ Press Control + F(or Command + F on | 3252 | [Premier League Table Ranking II](/solution/3200-3299/3252.Premier%20League%20Table%20Ranking%20II/README_EN.md) | `Database` | Medium | 🔒 | | 3262 | [Find Overlapping Shifts](/solution/3200-3299/3262.Find%20Overlapping%20Shifts/README_EN.md) | `Database` | Medium | 🔒 | | 3268 | [Find Overlapping Shifts II](/solution/3200-3299/3268.Find%20Overlapping%20Shifts%20II/README_EN.md) | `Database` | Hard | 🔒 | +| 3278 | [Find Candidates for Data Scientist Position II](/solution/3200-3299/3278.Find%20Candidates%20for%20Data%20Scientist%20Position%20II/README_EN.md) | | Medium | 🔒 | ## Copyright diff --git a/solution/README.md b/solution/README.md index 3421514747c21..902f25ae0b6ef 100644 --- a/solution/README.md +++ b/solution/README.md @@ -3288,6 +3288,7 @@ | 3275 | [第 K 近障碍物查询](/solution/3200-3299/3275.K-th%20Nearest%20Obstacle%20Queries/README.md) | | 中等 | 第 413 场周赛 | | 3276 | [选择矩阵中单元格的最大得分](/solution/3200-3299/3276.Select%20Cells%20in%20Grid%20With%20Maximum%20Score/README.md) | | 困难 | 第 413 场周赛 | | 3277 | [查询子数组最大异或值](/solution/3200-3299/3277.Maximum%20XOR%20Score%20Subarray%20Queries/README.md) | | 困难 | 第 413 场周赛 | +| 3278 | [Find Candidates for Data Scientist Position II](/solution/3200-3299/3278.Find%20Candidates%20for%20Data%20Scientist%20Position%20II/README.md) | | 中等 | 🔒 | ## 版权 diff --git a/solution/README_EN.md b/solution/README_EN.md index 3bc11ab59d315..6aa01bfcb62e3 100644 --- a/solution/README_EN.md +++ b/solution/README_EN.md @@ -3286,6 +3286,7 @@ Press Control + F(or Command + F on | 3275 | [K-th Nearest Obstacle Queries](/solution/3200-3299/3275.K-th%20Nearest%20Obstacle%20Queries/README_EN.md) | | Medium | Weekly Contest 413 | | 3276 | [Select Cells in Grid With Maximum Score](/solution/3200-3299/3276.Select%20Cells%20in%20Grid%20With%20Maximum%20Score/README_EN.md) | | Hard | Weekly Contest 413 | | 3277 | [Maximum XOR Score Subarray Queries](/solution/3200-3299/3277.Maximum%20XOR%20Score%20Subarray%20Queries/README_EN.md) | | Hard | Weekly Contest 413 | +| 3278 | [Find Candidates for Data Scientist Position II](/solution/3200-3299/3278.Find%20Candidates%20for%20Data%20Scientist%20Position%20II/README_EN.md) | | Medium | 🔒 | ## Copyright