Katkat

Highest Average-Salary Team in an Org Chart

AmazonApplied Scientist · Technical Screen

Last updated

Tests bottom-up tree traversal to compute subtree aggregates (sum and count) and identify an optimal node using multi-level tie-breaking rules.

Problem Statement

In an organization, each employee is represented by a node in an N-ary tree rooted at the CEO. Each employee has a unique integer id, a non-negative floating-point salary, and a list of reports (their direct subordinates).

A team led by an employee consists of that employee and all of their direct and indirect subordinates (i.e., the entire subtree rooted at that employee).

Write a function to find the employee id whose team has the highest average salary.

Tie-breaking Rules

If multiple teams have the same average salary:

  1. Choose the team with the larger team size (total number of members in the subtree).
  2. If still tied, choose the team with the smaller employee id.

Function Signature

class EmployeeNode:
    def __init__(self, id: int, salary: float, reports: list['EmployeeNode'] = None):
        self.id = id
        self.salary = salary
        self.reports = reports if reports is not None else []

def find_highest_average_team(root: EmployeeNode) -> int:
    pass

Input & Output Format

  • Input: root of type EmployeeNode, representing the CEO of the organization.
  • Output: An integer representing the id of the leader of the team with the highest average salary.

Examples

Example 1

         1 ($100k)
        /         \
   2 ($120k)     3 ($80k)
     /
 4 ($150k)

Team averages:

  • Node 4: salary sum = 150, size = 1, average = 150.0
  • Node 3: salary sum = 80, size = 1, average = 80.0
  • Node 2: salary sum = 120 + 150 = 270, size = 2, average = 135.0
  • Node 1: salary sum = 100 + 120 + 80 + 150 = 450, size = 4, average = 112.5

Output: 4
Explanation: Node 4's team has the highest average salary (150.0).

Example 2

         10 ($90k)
        /        \
   20 ($90k)    30 ($90k)

Team averages:

  • Node 20: average = 90.0, size = 1
  • Node 30: average = 90.0, size = 1
  • Node 10: average = 90.0, size = 3

Output: 10
Explanation: All nodes have an average salary of 90.0. Node 10 has the largest team size (3), breaking the tie.


Constraints

  • The number of employees N is between 1 and 50,000.
  • 0.0 <= salary <= 10^7
  • 1 <= id <= 10^9
  • All employee IDs are unique.
  • The org chart is a valid tree (no cycles, single root).

Edge Cases to Consider

  • A single-node organization (N = 1).
  • A strictly linear hierarchy (each manager has exactly one report).
  • Multiple teams with identical averages and sizes requiring the numerical id tie-break.
  • Floating-point precision differences when comparing averages.

Hints

Hint 1

Use a post-order (bottom-up) DFS traversal so that a parent node can compute its subtree sum and count directly from the return values of its children.

Hint 2

At each node, return a pair `(subtree_salary_sum, subtree_size)` to avoid redundant traversals, keeping the overall time complexity O(N).

Hint 3

Track the best node globally or via a helper object, applying the comparison tuple `(average, size, -id)` to handle the tie-breaking rules naturally.

Follow-up questions

  • What if a 'team' is only valid if the leader has at least one direct report (i.e., subtree size >= 2)? How does this affect the base cases and edge cases like an organization of size 1?
  • How would you avoid floating-point inaccuracies when comparing two subtree averages `sum1 / size1` and `sum2 / size2`?
  • If the org chart cannot fit into memory on a single machine and is stored in a distributed graph database, how would you compute the subtree aggregates efficiently?