/** * Given an array of Person objects, returns the root PersonTreeNode (the CEO). * @param {Person[]} employees - An array of Person objects representing all the employees of the company. * @returns {PersonTreeNode} The CEO of the organization. */ function generateTree(employees) { let ceo = null const visitedById = new Map() const visitedByManagerId = new Map() for (const employee of employees) { const node = new PersonTreeNode(employee) visitedById.set(employee.id, node) // Add any direct reports we've already visited for this manager const visitedDirectReports = visitedByManagerId.get(employee.id) if (Array.isArray(visitedDirectReports)) { node.directReports.push(...visitedDirectReports) } // Check if this is the CEO and skip the remaining logic in the loop if so if (employee.manager === null) { ceo = node continue } const managerNode = visitedById.get(employee.manager.id) if (managerNode) { // Add our node to its manager's direct reports (if manager visited) managerNode.directReports.push(node) } else { // Otherwise add node to map to be added to the manager's direct reports once we visit the manager const visitedDirectReportsForManager = visitedByManagerId.get( employee.manager.id, ) if (Array.isArray(visitedDirectReportsForManager)) { visitedDirectReportsForManager.push(node) } else { visitedByManagerId.set(employee.manager.id, [node]) } } } return ceo }