Facebook Pixel

690. Employee Importance

Problem Description

You are given information about employees in a company, where each employee has:

  • A unique ID number
  • An importance value (representing their contribution to the company)
  • A list of IDs representing their direct subordinates (employees who report directly to them)

The employee data is provided as an array of Employee objects, where each object contains:

  • employees[i].id - the unique identifier for the i-th employee
  • employees[i].importance - the importance value for the i-th employee
  • employees[i].subordinates - a list containing the IDs of all employees who directly report to the i-th employee

Your task is to calculate the total importance value for a given employee, which includes:

  1. The employee's own importance value
  2. The importance values of all their direct subordinates
  3. The importance values of all their indirect subordinates (subordinates of subordinates, and so on)

Given an employee ID, you need to return the sum of importance values for that employee and their entire reporting hierarchy beneath them.

For example, if Employee A has importance 5 and has two subordinates:

  • Employee B with importance 3 (who has no subordinates)
  • Employee C with importance 4 (who has Employee D as a subordinate with importance 2)

Then the total importance for Employee A would be: 5 + 3 + 4 + 2 = 14

Flowchart Walkthrough

First, let's pin down the algorithm using the Flowchart. Here's a step-by-step walkthrough:

Is it a graph?

  • Yes: The employee structure forms a graph where each employee is a node and the subordinate relationships are edges. Specifically, it's a hierarchical structure where employees point to their subordinates.

Is it a tree?

  • Yes: The employee hierarchy is actually a tree structure. Each employee (except the root/top-level employees) has exactly one manager (parent), and there are no cycles in the reporting structure. The subordinate relationships form a tree where we can traverse from any employee down through their reporting chain.

DFS

  • Since we identified this as a tree structure, the flowchart leads us directly to DFS (Depth-First Search) as the appropriate algorithm.

Conclusion: The flowchart suggests using DFS for this problem. This makes perfect sense because:

  1. We need to traverse the entire subtree rooted at the given employee
  2. We need to aggregate values (importance) from all nodes in the subtree
  3. DFS naturally handles the recursive nature of exploring each employee and all their subordinates (direct and indirect)

The DFS approach will:

  • Start at the given employee ID
  • Add that employee's importance value
  • Recursively visit all subordinates and add their importance values
  • Continue this process for all levels of the hierarchy until all subordinates are accounted for
Quick Interview Experience
Help others by sharing your interview experience
Have you seen this problem before?

Intuition

When we look at this problem, we need to find the total importance of an employee and all their subordinates (both direct and indirect). This immediately suggests we need to traverse through a hierarchical structure.

Think of the company structure like a family tree - each employee can have multiple "children" (subordinates), and those subordinates can have their own subordinates, and so on. To get the total importance, we need to visit every person in this specific branch of the tree.

The key insight is that this is a recursive problem: the total importance of any employee equals their own importance plus the sum of the total importance of each of their direct subordinates. This naturally breaks down into smaller subproblems of the same type.

Why DFS works perfectly here:

  1. We start with one employee and need to explore their entire "subtree" completely
  2. For each subordinate we encounter, we need to fully explore their subordinates before moving to the next sibling
  3. We're aggregating values as we traverse - each recursive call returns the importance sum for that subtree

The challenge is efficiently accessing employee data by ID. Since we need to look up employees by their ID repeatedly (when we encounter subordinate IDs), we first create a hash table d that maps each employee ID to their Employee object. This gives us O(1) lookup time.

The recursive DFS function then becomes straightforward:

  • Base case: An employee with no subordinates returns just their own importance
  • Recursive case: Return the employee's importance plus the sum of DFS calls on all their subordinates

This approach ensures we visit each employee exactly once and correctly accumulate all importance values in the hierarchy.

Learn more about Tree, Depth-First Search and Breadth-First Search patterns.

Solution Approach

The solution uses a Hash Table + DFS approach to efficiently calculate the total importance value.

Step 1: Build a Hash Table for Quick Lookup

First, we create a dictionary d that maps each employee's ID to their Employee object:

d = {e.id: e for e in employees}

This preprocessing step allows us to quickly access any employee's information by their ID in O(1) time, which is crucial since we'll need to look up subordinates repeatedly during traversal.

Step 2: Implement DFS Function

We define a recursive DFS function that calculates the total importance for an employee and all their subordinates:

def dfs(i: int) -> int:
    return d[i].importance + sum(dfs(j) for j in d[i].subordinates)

This function works as follows:

  • Takes an employee ID i as input
  • Returns the employee's own importance value: d[i].importance
  • Plus the sum of importance values from all subordinates: sum(dfs(j) for j in d[i].subordinates)
  • The sum() function with a generator expression recursively calls dfs() for each subordinate ID

Step 3: Start DFS from Target Employee

Finally, we initiate the DFS traversal from the given employee ID:

return dfs(id)

How the Recursion Works:

For each employee, the function:

  1. Adds their importance value to the result
  2. Recursively processes each subordinate in their list
  3. The recursion naturally handles all levels of the hierarchy
  4. When an employee has no subordinates (empty list), the sum() returns 0, serving as the base case

Time Complexity: O(n) where n is the total number of employees, as we visit each employee exactly once.

Space Complexity: O(n) for the hash table storage, plus O(h) for the recursion stack where h is the height of the employee hierarchy tree.

Ready to land your dream job?

Unlock your dream job with a 3-minute evaluator for a personalized learning plan!

Start Evaluator

Example Walkthrough

Let's walk through a concrete example to illustrate how the solution works.

Given Employee Data:

Employee 1: importance = 5, subordinates = [2, 3]
Employee 2: importance = 3, subordinates = []
Employee 3: importance = 3, subordinates = [4]
Employee 4: importance = 1, subordinates = []

Target: Calculate total importance for Employee ID = 1

Step 1: Build Hash Table

d = {
    1: Employee(id=1, importance=5, subordinates=[2,3]),
    2: Employee(id=2, importance=3, subordinates=[]),
    3: Employee(id=3, importance=3, subordinates=[4]),
    4: Employee(id=4, importance=1, subordinates=[])
}

Step 2: Execute DFS Traversal

Starting with dfs(1):

dfs(1):
  → d[1].importance = 5
  → sum(dfs(j) for j in [2, 3])
  
    dfs(2):
      → d[2].importance = 3
      → sum(dfs(j) for j in [])  // empty list
      → returns: 3 + 0 = 3
  
    dfs(3):
      → d[3].importance = 3
      → sum(dfs(j) for j in [4])
      
        dfs(4):
          → d[4].importance = 1
          → sum(dfs(j) for j in [])  // empty list
          → returns: 1 + 0 = 1
    
      → returns: 3 + 1 = 4

  → returns: 5 + (3 + 4) = 12

Visual Representation of the Traversal:

    Employee 1 (importance: 5)
    /                \
Employee 2          Employee 3
(importance: 3)     (importance: 3)
                         |
                    Employee 4
                    (importance: 1)

Total: 5 + 3 + 3 + 1 = 12

The DFS traversal visits nodes in this order: 1 → 2 → 3 → 4, accumulating importance values as it returns from each recursive call. Each employee's total contribution includes their own importance plus the sum returned by all their subordinates' recursive calls.

Solution Implementation

1"""
2# Definition for Employee.
3class Employee:
4    def __init__(self, id: int, importance: int, subordinates: List[int]):
5        self.id = id
6        self.importance = importance
7        self.subordinates = subordinates
8"""
9
10from typing import List
11
12
13class Solution:
14    def getImportance(self, employees: List["Employee"], id: int) -> int:
15        """
16        Calculate the total importance value of an employee and all their subordinates.
17      
18        Args:
19            employees: List of Employee objects
20            id: The ID of the employee whose total importance needs to be calculated
21          
22        Returns:
23            Total importance value of the employee and all subordinates
24        """
25      
26        def calculate_total_importance(employee_id: int) -> int:
27            """
28            Recursively calculate importance for an employee and their subordinates.
29          
30            Args:
31                employee_id: The ID of the current employee
32              
33            Returns:
34                Total importance including the employee and all subordinates
35            """
36            # Get the employee object from the map
37            employee = employee_map[employee_id]
38          
39            # Calculate total: employee's importance + sum of all subordinates' importance
40            subordinates_importance = sum(
41                calculate_total_importance(subordinate_id) 
42                for subordinate_id in employee.subordinates
43            )
44          
45            return employee.importance + subordinates_importance
46      
47        # Create a map for O(1) employee lookup by ID
48        employee_map = {employee.id: employee for employee in employees}
49      
50        # Start DFS from the given employee ID
51        return calculate_total_importance(id)
52
1/*
2// Definition for Employee.
3class Employee {
4    public int id;
5    public int importance;
6    public List<Integer> subordinates;
7};
8*/
9
10class Solution {
11    // HashMap to store employee ID to Employee object mapping for O(1) lookup
12    private final Map<Integer, Employee> employeeMap = new HashMap<>();
13
14    /**
15     * Calculates the total importance value of an employee and all their subordinates.
16     * 
17     * @param employees List of all employees in the organization
18     * @param id The ID of the employee whose total importance needs to be calculated
19     * @return The sum of importance values for the employee and all subordinates
20     */
21    public int getImportance(List<Employee> employees, int id) {
22        // Build a map for quick employee lookup by ID
23        for (Employee employee : employees) {
24            employeeMap.put(employee.id, employee);
25        }
26      
27        // Perform depth-first search starting from the target employee
28        return calculateTotalImportance(id);
29    }
30
31    /**
32     * Recursively calculates the importance sum using depth-first search.
33     * 
34     * @param employeeId The ID of the current employee being processed
35     * @return The total importance value including this employee and all subordinates
36     */
37    private int calculateTotalImportance(int employeeId) {
38        // Get the employee object from the map
39        Employee currentEmployee = employeeMap.get(employeeId);
40      
41        // Initialize sum with current employee's importance
42        int totalImportance = currentEmployee.importance;
43      
44        // Recursively add importance of all subordinates
45        for (int subordinateId : currentEmployee.subordinates) {
46            totalImportance += calculateTotalImportance(subordinateId);
47        }
48      
49        return totalImportance;
50    }
51}
52
1/*
2// Definition for Employee.
3class Employee {
4public:
5    int id;
6    int importance;
7    vector<int> subordinates;
8};
9*/
10
11class Solution {
12public:
13    int getImportance(vector<Employee*> employees, int id) {
14        // Build a hash map for O(1) employee lookup by ID
15        unordered_map<int, Employee*> employeeMap;
16        for (auto& employee : employees) {
17            employeeMap[employee->id] = employee;
18        }
19      
20        // Define recursive DFS function to calculate total importance
21        function<int(int)> calculateTotalImportance = [&](int employeeId) -> int {
22            // Start with current employee's importance value
23            int totalImportance = employeeMap[employeeId]->importance;
24          
25            // Recursively add importance of all subordinates
26            for (int subordinateId : employeeMap[employeeId]->subordinates) {
27                totalImportance += calculateTotalImportance(subordinateId);
28            }
29          
30            return totalImportance;
31        };
32      
33        // Start DFS from the given employee ID
34        return calculateTotalImportance(id);
35    }
36};
37
1/**
2 * Definition for Employee.
3 * class Employee {
4 *     id: number
5 *     importance: number
6 *     subordinates: number[]
7 *     constructor(id: number, importance: number, subordinates: number[]) {
8 *         this.id = (id === undefined) ? 0 : id;
9 *         this.importance = (importance === undefined) ? 0 : importance;
10 *         this.subordinates = (subordinates === undefined) ? [] : subordinates;
11 *     }
12 * }
13 */
14
15/**
16 * Calculates the total importance value of an employee and all their subordinates
17 * @param employees - Array of all employees in the organization
18 * @param id - The ID of the employee whose total importance needs to be calculated
19 * @returns The sum of importance values for the employee and all subordinates
20 */
21function getImportance(employees: Employee[], id: number): number {
22    // Create a map for O(1) employee lookup by ID
23    const employeeMap = new Map<number, Employee>();
24  
25    // Populate the map with all employees
26    for (const employee of employees) {
27        employeeMap.set(employee.id, employee);
28    }
29  
30    /**
31     * Depth-first search to calculate total importance
32     * @param employeeId - Current employee ID being processed
33     * @returns Total importance of the employee and all subordinates
34     */
35    const calculateTotalImportance = (employeeId: number): number => {
36        // Get the current employee from the map
37        const currentEmployee = employeeMap.get(employeeId)!;
38      
39        // Start with the current employee's importance value
40        let totalImportance = currentEmployee.importance;
41      
42        // Recursively add importance of all subordinates
43        for (const subordinateId of currentEmployee.subordinates) {
44            totalImportance += calculateTotalImportance(subordinateId);
45        }
46      
47        return totalImportance;
48    };
49  
50    // Start DFS from the given employee ID
51    return calculateTotalImportance(id);
52}
53

Time and Space Complexity

Time Complexity: O(n)

The algorithm first creates a dictionary mapping employee IDs to employee objects, which takes O(n) time where n is the number of employees. Then it performs a depth-first search (DFS) starting from the given employee ID. During the DFS traversal, each employee node is visited exactly once. For each employee visited, we access their importance value and iterate through their subordinates list. Since each employee appears exactly once in the organizational hierarchy (it's a tree structure), the total number of operations across all recursive calls is proportional to the number of employees. Therefore, the overall time complexity is O(n).

Space Complexity: O(n)

The space complexity consists of two main components:

  1. The dictionary d that stores the mapping from employee IDs to employee objects requires O(n) space to store all n employees.
  2. The recursive DFS call stack can go as deep as the height of the employee hierarchy tree. In the worst case (a completely linear hierarchy where each employee has at most one subordinate), the recursion depth could be O(n).

Therefore, the total space complexity is O(n).

Learn more about how to find time and space complexity quickly.

Common Pitfalls

1. Circular Dependencies in Employee Hierarchy

One critical pitfall that's often overlooked is the possibility of circular references in the employee hierarchy. If the input data contains a cycle (e.g., Employee A reports to B, B reports to C, and C reports back to A), the recursive DFS will enter an infinite loop, causing a stack overflow error.

Example of problematic data:

# Employee 1 has subordinate 2
# Employee 2 has subordinate 3  
# Employee 3 has subordinate 1 (creates a cycle!)

Solution: Add a visited set to track processed employees and prevent revisiting them:

class Solution:
    def getImportance(self, employees: List["Employee"], id: int) -> int:
        # Create employee map
        employee_map = {employee.id: employee for employee in employees}
      
        # Track visited employees to detect cycles
        visited = set()
      
        def calculate_total_importance(employee_id: int) -> int:
            # Check if we've already processed this employee (cycle detection)
            if employee_id in visited:
                return 0
          
            # Mark employee as visited
            visited.add(employee_id)
          
            # Get the employee object
            employee = employee_map[employee_id]
          
            # Calculate total importance
            subordinates_importance = sum(
                calculate_total_importance(subordinate_id) 
                for subordinate_id in employee.subordinates
            )
          
            return employee.importance + subordinates_importance
      
        return calculate_total_importance(id)

2. Invalid Employee IDs in Subordinates List

Another common issue is when a subordinate ID in the list doesn't correspond to any employee in the input data. This would cause a KeyError when trying to access employee_map[subordinate_id].

Solution: Add error handling or validation:

def calculate_total_importance(employee_id: int) -> int:
    # Validate employee ID exists
    if employee_id not in employee_map:
        return 0  # or raise ValueError(f"Employee {employee_id} not found")
  
    employee = employee_map[employee_id]
  
    subordinates_importance = sum(
        calculate_total_importance(subordinate_id) 
        for subordinate_id in employee.subordinates
        if subordinate_id in employee_map  # Skip invalid IDs
    )
  
    return employee.importance + subordinates_importance

3. Missing Initial Employee ID

The given id parameter might not exist in the employees list, causing an immediate KeyError.

Solution: Validate the input before processing:

class Solution:
    def getImportance(self, employees: List["Employee"], id: int) -> int:
        employee_map = {employee.id: employee for employee in employees}
      
        # Validate the target employee exists
        if id not in employee_map:
            return 0  # or raise ValueError(f"Employee {id} not found")
      
        # Continue with DFS...

These defensive programming practices make the solution more robust against malformed or unexpected input data.

Discover Your Strengths and Weaknesses: Take Our 3-Minute Quiz to Tailor Your Study Plan:

What's the relationship between a tree and a graph?


Recommended Readings

Want a Structured Path to Master System Design Too? Don’t Miss This!

Load More