Skip to content

Commit 582af17

Browse files
authored
feat: add solutions to lc problem: No.3278 (doocs#3467)
No.3278.Find Candidates for Data Scientist Position II
1 parent 0208336 commit 582af17

File tree

12 files changed

+449
-6
lines changed

12 files changed

+449
-6
lines changed

solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ function getDirections(root: TreeNode | null, startValue: number, destValue: num
314314
const left = lca(node.left, p, q);
315315
const right = lca(node.right, p, q);
316316

317-
return left && right ? node : left ?? right;
317+
return left && right ? node : (left ?? right);
318318
};
319319

320320
const dfs = (node: TreeNode | null, x: number, path: string[]): boolean => {
@@ -370,7 +370,7 @@ var getDirections = function (root, startValue, destValue) {
370370
const left = lca(node.left, p, q);
371371
const right = lca(node.right, p, q);
372372

373-
return left && right ? node : left ?? right;
373+
return left && right ? node : (left ?? right);
374374
};
375375

376376
const dfs = (node, x, path) => {

solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/README_EN.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ function getDirections(root: TreeNode | null, startValue: number, destValue: num
310310
const left = lca(node.left, p, q);
311311
const right = lca(node.right, p, q);
312312

313-
return left && right ? node : left ?? right;
313+
return left && right ? node : (left ?? right);
314314
};
315315

316316
const dfs = (node: TreeNode | null, x: number, path: string[]): boolean => {
@@ -366,7 +366,7 @@ var getDirections = function (root, startValue, destValue) {
366366
const left = lca(node.left, p, q);
367367
const right = lca(node.right, p, q);
368368

369-
return left && right ? node : left ?? right;
369+
return left && right ? node : (left ?? right);
370370
};
371371

372372
const dfs = (node, x, path) => {

solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/Solution.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ var getDirections = function (root, startValue, destValue) {
2020
const left = lca(node.left, p, q);
2121
const right = lca(node.right, p, q);
2222

23-
return left && right ? node : left ?? right;
23+
return left && right ? node : (left ?? right);
2424
};
2525

2626
const dfs = (node, x, path) => {

solution/2000-2099/2096.Step-By-Step Directions From a Binary Tree Node to Another/Solution.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ function getDirections(root: TreeNode | null, startValue: number, destValue: num
2020
const left = lca(node.left, p, q);
2121
const right = lca(node.right, p, q);
2222

23-
return left && right ? node : left ?? right;
23+
return left && right ? node : (left ?? right);
2424
};
2525

2626
const dfs = (node: TreeNode | null, x: number, path: string[]): boolean => {

solution/2200-2299/2205.The Number of Users That Are Eligible for Discount/README.md

+4
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ startDate = 2022-03-08, endDate = 2022-03-20, minAmount = 1000
6666
- 用户 2 在时间间隔内有一次购买,但金额小于 minAmount。
6767
- 用户 3 是唯一一个购买行为同时满足这两个条件的用户。</pre>
6868

69+
<p>&nbsp;</p>
70+
71+
<p><b>重要提示:</b>此问题与 <a href="https://leetcode.cn/problems/the-users-that-are-eligible-for-discount/">2230. 查找可享受优惠的用户</a>&nbsp;基本相同。</p>
72+
6973
<!-- description:end -->
7074

7175
## 解法
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
---
2+
comments: true
3+
difficulty: 中等
4+
edit_url: https://github.com/doocs/leetcode/edit/main/solution/3200-3299/3278.Find%20Candidates%20for%20Data%20Scientist%20Position%20II/README.md
5+
tags:
6+
- 数据库
7+
---
8+
9+
<!-- problem:start -->
10+
11+
# [3278. Find Candidates for Data Scientist Position II 🔒](https://leetcode.cn/problems/find-candidates-for-data-scientist-position-ii)
12+
13+
[English Version](/solution/3200-3299/3278.Find%20Candidates%20for%20Data%20Scientist%20Position%20II/README_EN.md)
14+
15+
## 题目描述
16+
17+
<!-- description:start -->
18+
19+
<p>Table: <font face="monospace"><code>Candidates</code></font></p>
20+
21+
<pre>
22+
+--------------+---------+
23+
| Column Name | Type |
24+
+--------------+---------+
25+
| candidate_id | int |
26+
| skill | varchar |
27+
| proficiency | int |
28+
+--------------+---------+
29+
(candidate_id, skill) is the unique key for this table.
30+
Each row includes candidate_id, skill, and proficiency level (1-5).
31+
</pre>
32+
33+
<p>Table: <font face="monospace"><code>Projects</code></font></p>
34+
35+
<pre>
36+
+--------------+---------+
37+
| Column Name | Type |
38+
+--------------+---------+
39+
| project_id | int |
40+
| skill | varchar |
41+
| importance | int |
42+
+--------------+---------+
43+
(project_id, skill) is the primary key for this table.
44+
Each row includes project_id, required skill, and its importance (1-5) for the project.
45+
</pre>
46+
47+
<p>Leetcode is staffing for multiple data science projects. Write a solution to find the <strong>best candidate</strong> for<strong> each project</strong> based on the following criteria:</p>
48+
49+
<ol>
50+
<li>Candidates must have <strong>all</strong> the skills required for a project.</li>
51+
<li>Calculate a <strong>score</strong> for each candidate-project pair as follows:
52+
<ul>
53+
<li><strong>Start</strong> with <code>100</code> points</li>
54+
<li><strong>Add</strong> <code>10</code> points for each skill where <strong>proficiency &gt; importance</strong></li>
55+
<li><strong>Subtract</strong> <code>5</code> points for each skill where <strong>proficiency &lt; importance</strong></li>
56+
</ul>
57+
</li>
58+
</ol>
59+
60+
<p>Include only the top candidate (highest score) for each project. If there&rsquo;s a <strong>tie</strong>, choose the candidate with the <strong>lower</strong> <code>candidate_id</code>. If there is <strong>no suitable candidate</strong> for a project, <strong>do not return</strong>&nbsp;that project.</p>
61+
62+
<p>Return a result table ordered by <code>project_id</code> in ascending order.</p>
63+
64+
<p>The result format is in the following example.</p>
65+
66+
<p>&nbsp;</p>
67+
<p><strong class="example">Example:</strong></p>
68+
69+
<div class="example-block">
70+
<p><strong>Input:</strong></p>
71+
72+
<p><code>Candidates</code> table:</p>
73+
74+
<pre class="example-io">
75+
+--------------+-----------+-------------+
76+
| candidate_id | skill | proficiency |
77+
+--------------+-----------+-------------+
78+
| 101 | Python | 5 |
79+
| 101 | Tableau | 3 |
80+
| 101 | PostgreSQL| 4 |
81+
| 101 | TensorFlow| 2 |
82+
| 102 | Python | 4 |
83+
| 102 | Tableau | 5 |
84+
| 102 | PostgreSQL| 4 |
85+
| 102 | R | 4 |
86+
| 103 | Python | 3 |
87+
| 103 | Tableau | 5 |
88+
| 103 | PostgreSQL| 5 |
89+
| 103 | Spark | 4 |
90+
+--------------+-----------+-------------+
91+
</pre>
92+
93+
<p><code>Projects</code> table:</p>
94+
95+
<pre class="example-io">
96+
+-------------+-----------+------------+
97+
| project_id | skill | importance |
98+
+-------------+-----------+------------+
99+
| 501 | Python | 4 |
100+
| 501 | Tableau | 3 |
101+
| 501 | PostgreSQL| 5 |
102+
| 502 | Python | 3 |
103+
| 502 | Tableau | 4 |
104+
| 502 | R | 2 |
105+
+-------------+-----------+------------+
106+
</pre>
107+
108+
<p><strong>Output:</strong></p>
109+
110+
<pre class="example-io">
111+
+-------------+--------------+-------+
112+
| project_id | candidate_id | score |
113+
+-------------+--------------+-------+
114+
| 501 | 101 | 105 |
115+
| 502 | 102 | 130 |
116+
+-------------+--------------+-------+
117+
</pre>
118+
119+
<p><strong>Explanation:</strong></p>
120+
121+
<ul>
122+
<li>For Project 501, Candidate 101 has the highest score of 105. All other candidates have the same score but Candidate 101 has the lowest candidate_id among them.</li>
123+
<li>For Project 502, Candidate 102 has the highest score of 130.</li>
124+
</ul>
125+
126+
<p>The output table is ordered by project_id in ascending order.</p>
127+
</div>
128+
129+
<!-- description:end -->
130+
131+
## 解法
132+
133+
<!-- solution:start -->
134+
135+
### 方法一:等值连接 + 分组统计 + 窗口函数
136+
137+
我们可以将表 `Candidates` 和表 `Projects` 通过 `skill` 列进行等值连接,统计每个候选人在每个项目中匹配的技能数量、总分数,记录在表 `S` 中。
138+
139+
然后我们再次统计每个项目所需的技能数量,记录在表 `T` 中。
140+
141+
接着我们将表 `S` 和表 `T` 通过 `project_id` 列进行等值连接,筛选出匹配的技能数量等于所需技能数量的候选人,记录在表 `P` 中,并计算每个项目的候选人排名,字段为 `rk`
142+
143+
最后我们筛选出每个项目的排名为 1 的候选人,即为最佳候选人。
144+
145+
<!-- tabs:start -->
146+
147+
#### MySQL
148+
149+
```sql
150+
WITH
151+
S AS (
152+
SELECT
153+
candidate_id,
154+
project_id,
155+
COUNT(*) matched_skills,
156+
SUM(
157+
CASE
158+
WHEN proficiency > importance THEN 10
159+
WHEN proficiency < importance THEN -5
160+
ELSE 0
161+
END
162+
) + 100 AS score
163+
FROM
164+
Candidates
165+
JOIN Projects USING (skill)
166+
GROUP BY 1, 2
167+
),
168+
T AS (
169+
SELECT project_id, COUNT(1) required_skills
170+
FROM Projects
171+
GROUP BY 1
172+
),
173+
P AS (
174+
SELECT
175+
project_id,
176+
candidate_id,
177+
score,
178+
RANK() OVER (
179+
PARTITION BY project_id
180+
ORDER BY score DESC, candidate_id
181+
) rk
182+
FROM
183+
S
184+
JOIN T USING (project_id)
185+
WHERE matched_skills = required_skills
186+
)
187+
SELECT project_id, candidate_id, score
188+
FROM P
189+
WHERE rk = 1
190+
ORDER BY 1;
191+
```
192+
193+
<!-- tabs:end -->
194+
195+
<!-- solution:end -->
196+
197+
<!-- problem:end -->

0 commit comments

Comments
 (0)