Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add solutions to lc problem: No.3482 #4151

Merged
merged 1 commit into from
Mar 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 83 additions & 1 deletion solution/3400-3499/3482.Analyze Organization Hierarchy/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ tags:

<pre>
+----------------+---------+
| Column Name | Type |
| Column Name | Type |
+----------------+---------+
| employee_id | int |
| employee_name | varchar |
Expand Down Expand Up @@ -151,7 +151,89 @@ manager_id is null for the top-level manager (CEO).
#### MySQL

```sql
# Write your MySQL query statement below
WITH RECURSIVE
level_cte AS (
SELECT employee_id, manager_id, 1 AS level, salary FROM Employees
UNION ALL
SELECT a.employee_id, b.manager_id, level + 1, a.salary
FROM
level_cte a
JOIN Employees b ON b.employee_id = a.manager_id
),
employee_with_level AS (
SELECT a.employee_id, a.employee_name, a.salary, b.level
FROM
Employees a,
(SELECT employee_id, level FROM level_cte WHERE manager_id IS NULL) b
WHERE a.employee_id = b.employee_id
)
SELECT
a.employee_id,
a.employee_name,
a.level,
COALESCE(b.team_size, 0) AS team_size,
a.salary + COALESCE(b.budget, 0) AS budget
FROM
employee_with_level a
LEFT JOIN (
SELECT manager_id AS employee_id, COUNT(*) AS team_size, SUM(salary) AS budget
FROM level_cte
WHERE manager_id IS NOT NULL
GROUP BY manager_id
) b
ON a.employee_id = b.employee_id
ORDER BY level, budget DESC, employee_name;
```

#### Pandas

```python
import pandas as pd


def analyze_organization_hierarchy(employees: pd.DataFrame) -> pd.DataFrame:
# 初始化 CEO (level 1)
employees = employees.copy()
employees["level"] = None
ceo_id = employees.loc[employees["manager_id"].isna(), "employee_id"].values[0]
employees.loc[employees["employee_id"] == ceo_id, "level"] = 1

# 递归计算层级
def compute_levels(emp_df, level):
next_level_ids = emp_df[emp_df["level"] == level]["employee_id"].tolist()
if not next_level_ids:
return
emp_df.loc[emp_df["manager_id"].isin(next_level_ids), "level"] = level + 1
compute_levels(emp_df, level + 1)

compute_levels(employees, 1)

# 计算 team_size 和 budget
team_size = {eid: 0 for eid in employees["employee_id"]}
budget = {
eid: salary
for eid, salary in zip(employees["employee_id"], employees["salary"])
}

for eid in sorted(employees["employee_id"], reverse=True):
manager_id = employees.loc[
employees["employee_id"] == eid, "manager_id"
].values[0]
if pd.notna(manager_id):
team_size[manager_id] += team_size[eid] + 1
budget[manager_id] += budget[eid]

# 生成最终 DataFrame
employees["team_size"] = employees["employee_id"].map(team_size)
employees["budget"] = employees["employee_id"].map(budget)

# 按 level 升序,budget 降序,employee_name 升序排序
employees = employees.sort_values(
by=["level", "budget", "employee_name"], ascending=[True, False, True]
)

return employees[["employee_id", "employee_name", "level", "team_size", "budget"]]
```

<!-- tabs:end -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ tags:

<pre>
+----------------+---------+
| Column Name | Type |
| Column Name | Type |
+----------------+---------+
| employee_id | int |
| employee_name | varchar |
Expand Down Expand Up @@ -151,7 +151,84 @@ manager_id is null for the top-level manager (CEO).
#### MySQL

```sql
# Write your MySQL query statement below
WITH RECURSIVE
level_cte AS (
SELECT employee_id, manager_id, 1 AS level, salary FROM Employees
UNION ALL
SELECT a.employee_id, b.manager_id, level + 1, a.salary
FROM
level_cte a
JOIN Employees b ON b.employee_id = a.manager_id
),
employee_with_level AS (
SELECT a.employee_id, a.employee_name, a.salary, b.level
FROM
Employees a,
(SELECT employee_id, level FROM level_cte WHERE manager_id IS NULL) b
WHERE a.employee_id = b.employee_id
)
SELECT
a.employee_id,
a.employee_name,
a.level,
COALESCE(b.team_size, 0) AS team_size,
a.salary + COALESCE(b.budget, 0) AS budget
FROM
employee_with_level a
LEFT JOIN (
SELECT manager_id AS employee_id, COUNT(*) AS team_size, SUM(salary) AS budget
FROM level_cte
WHERE manager_id IS NOT NULL
GROUP BY manager_id
) b
ON a.employee_id = b.employee_id
ORDER BY level, budget DESC, employee_name;
```

#### Pandas

```python
import pandas as pd

def analyze_organization_hierarchy(employees: pd.DataFrame) -> pd.DataFrame:
# Copy the input DataFrame to avoid modifying the original
employees = employees.copy()
employees['level'] = None

# Identify the CEO (level 1)
ceo_id = employees.loc[employees['manager_id'].isna(), 'employee_id'].values[0]
employees.loc[employees['employee_id'] == ceo_id, 'level'] = 1

# Recursively compute employee levels
def compute_levels(emp_df, level):
next_level_ids = emp_df[emp_df['level'] == level]['employee_id'].tolist()
if not next_level_ids:
return
emp_df.loc[emp_df['manager_id'].isin(next_level_ids), 'level'] = level + 1
compute_levels(emp_df, level + 1)

compute_levels(employees, 1)

# Initialize team size and budget dictionaries
team_size = {eid: 0 for eid in employees['employee_id']}
budget = {eid: salary for eid, salary in zip(employees['employee_id'], employees['salary'])}

# Compute team size and budget for each employee
for eid in sorted(employees['employee_id'], reverse=True):
manager_id = employees.loc[employees['employee_id'] == eid, 'manager_id'].values[0]
if pd.notna(manager_id):
team_size[manager_id] += team_size[eid] + 1
budget[manager_id] += budget[eid]

# Map computed team size and budget to employees DataFrame
employees['team_size'] = employees['employee_id'].map(team_size)
employees['budget'] = employees['employee_id'].map(budget)

# Sort the final result by level (ascending), budget (descending), and employee name (ascending)
employees = employees.sort_values(by=['level', 'budget', 'employee_name'], ascending=[True, False, True])

return employees[['employee_id', 'employee_name', 'level', 'team_size', 'budget']]
```

<!-- tabs:end -->
Expand Down
48 changes: 48 additions & 0 deletions solution/3400-3499/3482.Analyze Organization Hierarchy/Solution.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import pandas as pd


def analyze_organization_hierarchy(employees: pd.DataFrame) -> pd.DataFrame:
# Copy the input DataFrame to avoid modifying the original
employees = employees.copy()
employees["level"] = None

# Identify the CEO (level 1)
ceo_id = employees.loc[employees["manager_id"].isna(), "employee_id"].values[0]
employees.loc[employees["employee_id"] == ceo_id, "level"] = 1

# Recursively compute employee levels
def compute_levels(emp_df, level):
next_level_ids = emp_df[emp_df["level"] == level]["employee_id"].tolist()
if not next_level_ids:
return
emp_df.loc[emp_df["manager_id"].isin(next_level_ids), "level"] = level + 1
compute_levels(emp_df, level + 1)

compute_levels(employees, 1)

# Initialize team size and budget dictionaries
team_size = {eid: 0 for eid in employees["employee_id"]}
budget = {
eid: salary
for eid, salary in zip(employees["employee_id"], employees["salary"])
}

# Compute team size and budget for each employee
for eid in sorted(employees["employee_id"], reverse=True):
manager_id = employees.loc[
employees["employee_id"] == eid, "manager_id"
].values[0]
if pd.notna(manager_id):
team_size[manager_id] += team_size[eid] + 1
budget[manager_id] += budget[eid]

# Map computed team size and budget to employees DataFrame
employees["team_size"] = employees["employee_id"].map(team_size)
employees["budget"] = employees["employee_id"].map(budget)

# Sort the final result by level (ascending), budget (descending), and employee name (ascending)
employees = employees.sort_values(
by=["level", "budget", "employee_name"], ascending=[True, False, True]
)

return employees[["employee_id", "employee_name", "level", "team_size", "budget"]]
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Write your MySQL query statement below
WITH RECURSIVE
level_cte AS (
SELECT employee_id, manager_id, 1 AS level, salary FROM Employees
UNION ALL
SELECT a.employee_id, b.manager_id, level + 1, a.salary
FROM
level_cte a
JOIN Employees b ON b.employee_id = a.manager_id
),
employee_with_level AS (
SELECT a.employee_id, a.employee_name, a.salary, b.level
FROM
Employees a,
(SELECT employee_id, level FROM level_cte WHERE manager_id IS NULL) b
WHERE a.employee_id = b.employee_id
)
SELECT
a.employee_id,
a.employee_name,
a.level,
COALESCE(b.team_size, 0) AS team_size,
a.salary + COALESCE(b.budget, 0) AS budget
FROM
employee_with_level a
LEFT JOIN (
SELECT manager_id AS employee_id, COUNT(*) AS team_size, SUM(salary) AS budget
FROM level_cte
WHERE manager_id IS NOT NULL
GROUP BY manager_id
) b
ON a.employee_id = b.employee_id
ORDER BY level, budget DESC, employee_name;