Open In App

Find number of Employees Under every Manager

Last Updated : 16 Mar, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given a dictionary that contains mapping of employee and his manager as a number of (employee, manager) pairs like below. 

{ "A", "C" },
{ "B", "C" },
{ "C", "F" },
{ "D", "E" },
{ "E", "F" },
{ "F", "F" } 

In this example C is manager of A, 
C is also manager of B, F is manager 
of C and so on.

Write a function to get no of employees under each manager in the hierarchy not just their direct reports. It may be assumed that an employee directly reports to only one manager. In the above dictionary the root node/ceo is listed as reporting to himself. 

Output should be a Dictionary that contains following. 

A - 0  
B - 0
C - 2
D - 0
E - 1
F - 5 

This question might be solved differently but i followed this and found interesting, so sharing:

 1. Create a reverse map with Manager->DirectReportingEmployee 
    combination. Off-course employee will be multiple so Value 
    in Map is List of Strings.
        "C" --> "A", "B",
        "E" --> "D" 
        "F" --> "C", "E", "F"
 
2. Now use the given employee-manager map to iterate  and at 
   the same time use newly reverse map to find the count of 
   employees under manager.
   
   Let the map created in step 2 be 'mngrEmpMap' 
   Do following for every employee 'emp'.
     a) If 'emp' is not present in 'mngrEmpMap' 
          Count under 'emp' is 0 [Nobody reports to 'emp']
     b) If 'emp' is present in 'mngrEmpMap' 
          Use the list of direct reports from map 'mngrEmpMap'
          and recursively calculate number of total employees
          under 'emp'. 

A trick in step 2.b is to use memorization(Dynamic programming) while finding number of employees under a manager so that we don’t need to find number of employees again for any of the employees. In the below code populateResultUtil() is the recursive function that uses memoization to avoid re-computation of same results.

Below is Java implementation of above ideas

C++




#include <bits/stdc++.h>
using namespace std;
 
// This is a recursive function to fill count for 'mngr'
// using mngrEmpMap.  This function uses memoization to
// avoid re- computations of subproblems.
int populateResultUtil(
    string mngr,
    unordered_map<string, vector<string> > mngrEmpMap,
    map<string, int>& result)
{
    int count = 0;
 
    // means employee is not a manager of any other employee
    if (mngrEmpMap.find(mngr) == mngrEmpMap.end()) {
        result.insert({ mngr, 0 });
        return 0;
    }
 
    // this employee count has already been done by this
    // method, so avoid re-computation
    else if (result.find(mngr) != result.end()) {
        count = result[mngr];
    }
    else {
        vector<string> directReportEmpList
            = mngrEmpMap[mngr];
        count = directReportEmpList.size();
        for (int i = 0; i < directReportEmpList.size();
             i++) {
            count += populateResultUtil(
                directReportEmpList[i], mngrEmpMap, result);
        }
        result.insert({ mngr, count });
    }
    return count;
}
 
// This function populates 'result' for given input
// 'dataset'
void populateResult(unordered_map<string, string> dataset)
{
 
    // A hashmap to store result. It stores count of
    // employees under every employee, the count may by 0
    // also
    map<string, int> result;
 
    // To store reverse of original map, each key will have
    // 0 to multiple values
    unordered_map<string, vector<string> > mngrEmpMap;
 
    // To fill mngrEmpMap, iterate through the given map
    for (auto d : dataset) {
        string emp = d.first;
        string mngr = d.second;
        if (emp != mngr) // excluding emp-emp entry
        {
            // If 'emp' is the first employee under 'mngr'
            if (mngrEmpMap.find(mngr) == mngrEmpMap.end()) {
                vector<string> directReportList;
                directReportList.push_back(emp);
                // add a new entry for the mngr with empty
                // directReportList
                mngrEmpMap[mngr] = directReportList;
            }
            else {
                // Get the previous list of direct reports
                // under current 'mngr' and add the current
                // 'emp' to the list
                mngrEmpMap[mngr].push_back(emp);
            }
        }
    }
 
    // Now use manager-Emp map built above to populate
    // result with use of populateResultUtil()
 
    // note- we are iterating over original emp-manager map
    // and will use mngr-emp map in helper to get the count
    for (auto d : dataset) {
        populateResultUtil(d.first, mngrEmpMap, result);
    }
 
    map<string, int>::iterator itr;
    auto end = result.end();
    end--; // end to second last;
 
    cout << "result = {";
    for (itr = result.begin(); itr != end; itr++) {
        cout << itr->first << "=" << itr->second << ", ";
    }
    cout << itr->first << "=" << itr->second;
    cout << "}";
}
 
int main()
{
    unordered_map<string, string> dataset;
    dataset["A"] = "C";
    dataset["B"] = "C";
    dataset["C"] = "F";
    dataset["D"] = "E";
    dataset["E"] = "F";
    dataset["F"] = "F";
 
    populateResult(dataset);
 
    return 0;
}
 
// This code is contributed by Snigdha Patil


Java




// Java program to find number of persons under every employee
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
public class NumberEmployeeUnderManager
{
    // A hashmap to store result. It stores count of employees
    // under every employee, the count may by 0 also
    static Map<String,Integer> result =
                             new HashMap<String, Integer>();
 
    // Driver function
    public static void main(String[] args)
    {
        Map<String, String> dataSet = new HashMap<String, String>();
        dataSet.put("A", "C");
        dataSet.put("B", "C");
        dataSet.put("C", "F");
        dataSet.put("D", "E");
        dataSet.put("E", "F");
        dataSet.put("F", "F");
 
        populateResult(dataSet);
        System.out.println("result = " + result);
    }
 
    // This function populates 'result' for given input 'dataset'
    private static void populateResult(Map<String, String> dataSet)
    {
        // To store reverse of original map, each key will have 0
        // to multiple values
        Map<String, List<String>> mngrEmpMap =
                                  new HashMap<String, List<String>>();
 
        // To fill mngrEmpMap, iterate through the given map
        for (Map.Entry<String,String> entry: dataSet.entrySet())
        {
            String emp = entry.getKey();
            String mngr = entry.getValue();
            if (!emp.equals(mngr)) // excluding emp-emp entry
            {
                // Get the previous list of direct reports under
                // current 'mgr' and add the current 'emp' to the list
                List<String> directReportList = mngrEmpMap.get(mngr);
 
                // If 'emp' is the first employee under 'mgr'
                if (directReportList == null)
                {
                    directReportList = new ArrayList<String>();
                    // add a new entry for the mngr with empty directReportList
                    mngrEmpMap.put(mngr, directReportList);
                }
                directReportList.add(emp);
            }
        }
 
        // Now use manager-Emp map built above to populate result
        // with use of populateResultUtil()
 
        // note- we are iterating over original emp-manager map and
        // will use mngr-emp map in helper to get the count
        for (String mngr: dataSet.keySet())
            populateResultUtil(mngr, mngrEmpMap);
    }
 
    // This is a recursive function to fill count for 'mgr' using
    // mngrEmpMap.  This function uses memoization to avoid re-
    // computations of subproblems.
    private static int populateResultUtil(String mngr,
                               Map<String, List<String>> mngrEmpMap)
    {
        int count = 0;
 
        // means employee is not a manager of any other employee
        if (!mngrEmpMap.containsKey(mngr))
        {
            result.put(mngr, 0);
            return 0;
        }
 
        // this employee count has already been done by this
        // method, so avoid re-computation
        else if (result.containsKey(mngr))
            count = result.get(mngr);
 
        else
        {
            List<String> directReportEmpList = mngrEmpMap.get(mngr);
            count = directReportEmpList.size();
            for (String directReportEmp: directReportEmpList)
               count +=  populateResultUtil(directReportEmp, mngrEmpMap);
 
            result.put(mngr, count);
        }
        return count;
    }
}


Python3




class Solution():
    def __init__(self):
        pass
 
    def assignAndPrint(self,t):
        #We will directly permute over t. Access 2nd element(i.e. manager) of certain tuple and assign the relation in
        # dictionary. We will assign list of employees to a particular manager so that with iterations, we can append
        # more employees to that list and list grows.
        d = dict()
        for pair in t:
            if(pair[0]==pair[1]):  # because we dont want to assign self managing role
                continue
            if pair[0] not in d:  # assign employee a empty list of employees
                d[pair[0]] = []
            # for managers -
            if pair[1] not in d:
                d[pair[1]] = [pair[0]]
            else:
                d[pair[1]].append(pair[0])
        #print(d)
        # now we know how many employees are directly under a particular manager.
        # now lets count the total number of employees under a particular manager.
        c = dict()   # store    manager:count of employee    as key value
        for manager in d:
            c[manager] = len(d[manager])
            for employee in d[manager]:
                c[manager] += len(d[employee])
            print("{} : {}".format(manager,c[manager]))     # prints which manager has total how many employees
        # Note : Employees having no employees under are also considered as managed with 0 employees.
 
 
if __name__=="__main__":
    # t is tuple containing employee and boss pair.
    t = (("A", "C"),("B", "C"),("C", "F"),("D", "E"),("E", "F"),("F", "F"))
    obj = Solution()
    obj.assignAndPrint(t)


C#




//c# implementation of the above approach
using System;
using System.Collections.Generic;
 
class GFG
{
    static int PopulateResultUtil(
        string mngr,
        Dictionary<string, List<string>> mngrEmpMap,
        Dictionary<string, int> result)
    {
        int count = 0;
 
        if (!mngrEmpMap.ContainsKey(mngr)) // Employee is not a manager of any other employee
        {
            result[mngr] = 0;
            return 0;
        }
        else if (result.ContainsKey(mngr)) // Employee count has already been done by this method, so avoid re-computation
        {
            count = result[mngr];
        }
        else
        {
            List<string> directReportEmpList = mngrEmpMap[mngr];
            count = directReportEmpList.Count;
            for (int i = 0; i < directReportEmpList.Count; i++)
            {
                count += PopulateResultUtil(
                    directReportEmpList[i], mngrEmpMap, result);
            }
            result[mngr] = count;
        }
        return count;
    }
 
    static void PopulateResult(Dictionary<string, string> dataset)
    {
        Dictionary<string, int> result = new Dictionary<string, int>();
        Dictionary<string, List<string>> mngrEmpMap = new Dictionary<string, List<string>>();
 
        // Fill mngrEmpMap, iterate through the given map
        foreach (var d in dataset)
        {
            string emp = d.Key;
            string mngr = d.Value;
 
            if (emp != mngr) // Excluding emp-emp entry
            {
                if (!mngrEmpMap.ContainsKey(mngr)) // First employee under 'mngr'
                {
                    List<string> directReportList = new List<string>();
                    directReportList.Add(emp);
                    mngrEmpMap[mngr] = directReportList;
                }
                else // Add current 'emp' to the list of direct reports under current 'mngr'
                {
                    mngrEmpMap[mngr].Add(emp);
                }
            }
        }
 
        // Use manager-Emp map to populate result with use of PopulateResultUtil()
        foreach (var d in dataset)
        {
            PopulateResultUtil(d.Key, mngrEmpMap, result);
        }
 
        // Output result dictionary
        Console.Write("result = {");
        foreach (var r in result)
        {
           
            Console.Write(r.Key + "=" + r.Value + ", ");
        }
        Console.Write("}");
    }
 
    static void Main(string[] args)
    {
        Dictionary<string, string> dataset = new Dictionary<string, string>();
        dataset["A"] = "C";
        dataset["B"] = "C";
        dataset["C"] = "F";
        dataset["D"] = "E";
        dataset["E"] = "F";
        dataset["F"] = "F";
 
        PopulateResult(dataset);
    }
}


Javascript




// A hashmap to store result. It stores count of employees
// under every employee, the count may be 0 also
let result = new Map();
 
// Driver function
function main() {
    let dataSet = new Map();
    dataSet.set("A", "C");
    dataSet.set("B", "C");
    dataSet.set("C", "F");
    dataSet.set("D", "E");
    dataSet.set("E", "F");
    dataSet.set("F", "F");
 
    populateResult(dataSet);
    console.log("result = ", result);
}
 
// This function populates 'result' for given input 'dataset'
function populateResult(dataSet) {
    // To store reverse of original map, each key will have 0
    // to multiple values
    let mngrEmpMap = new Map();
 
    // To fill mngrEmpMap, iterate through the given map
    for (let [emp, mngr] of dataSet) {
        if (emp !== mngr) { // excluding emp-emp entry
            // Get the previous list of direct reports under
            // current 'mgr' and add the current 'emp' to the list
            let directReportList = mngrEmpMap.get(mngr);
 
            // If 'emp' is the first employee under 'mgr'
            if (directReportList === undefined) {
                directReportList = [];
                // add a new entry for the mngr with empty directReportList
                mngrEmpMap.set(mngr, directReportList);
            }
            directReportList.push(emp);
        }
    }
 
    // Now use manager-Emp map built above to populate result
    // with use of populateResultUtil()
 
    // note- we are iterating over original emp-manager map and
    // will use mngr-emp map in helper to get the count
    for (let mngr of dataSet.keys()) {
        populateResultUtil(mngr, mngrEmpMap);
    }
}
 
// This is a recursive function to fill count for 'mgr' using
// mngrEmpMap. This function uses memoization to avoid re-
// computations of subproblems.
function populateResultUtil(mngr, mngrEmpMap) {
    let count = 0;
 
    // means employee is not a manager of any other employee
    if (!mngrEmpMap.has(mngr)) {
        result.set(mngr, 0);
        return 0;
    }
 
    // this employee count has already been done by this
    // method, so avoid re-computation
    else if (result.has(mngr)) {
        count = result.get(mngr);
    }
 
    else {
        let directReportEmpList = mngrEmpMap.get(mngr);
        count = directReportEmpList.length;
        for (let directReportEmp of directReportEmpList) {
            count += populateResultUtil(directReportEmp, mngrEmpMap);
        }
 
        result.set(mngr, count);
    }
    return count;
}
 
// call the main function
main();


Output

result = {A=0, B=0, C=2, D=0, E=1, F=5}

Time Complexity: O(n*log n)
Auxiliary Space: O(n)



Previous Article
Next Article

Similar Reads

Find smallest number with given number of digits and sum of digits under given constraints
Given two integers S and D, the task is to find the number having D number of digits and the sum of its digits as S such that the difference between the maximum and the minimum digit in the number is as minimum as possible. If multiple such numbers are possible, print the smallest number.Examples: Input: S = 25, D = 4 Output: 6667 The difference be
7 min read
Connecting employees from different companies
A tech fest is buzzing with activity as employees from various companies aim to connect and collaborate. Each connection between employees X and Y is represented as "C X Y" which leads to a merger of their respective companies if they belong to different ones. Initially, N employees represent N companies. You need to implement a system that handles
8 min read
Nearest smaller number to N having multiplicative inverse under modulo N equal to that number
Given a prime number N, the task is to find the closest smaller number than N such that modulo multiplicative inverse of a number under modulo N is equal to the number itself. Examples: Input: N = 7Output: 6Explanation:Modulo multiplicative inverse of all possible natural numbers from 1 to less than N are:Modulo multiplicative inverse of 1 under mo
3 min read
Find subset with maximum sum under given condition
Given values[] and labels[] of n items and a positive integer limit, We need to choose a subset of these items in such a way that the number of the same type of label in the subset should be &lt;= limit and sum of values are maximum among all possible subset choices. Examples: Input: values[] = [5, 3, 7, 1, 2], labels[] = [5, 7, 7, 7, 6], limit = 2
6 min read
Find the final X and Y when they are Altering under given condition
Given initial values of two positive integers X and Y, Find the final value of X and Y according to the below alterations: 1. If X=0 or Y=0, terminate the process. Else, go to step 2; 2. If X &gt;= 2*Y, then change the value of X to X - 2*Y, and repeat step 1. Else, go to step 3; 3. If Y &gt;= 2*X, then assign the value of Y to Y - 2*X, and repeat
15+ min read
Find whether a day fall under the GEEK year
The geeks living in the Geekland follow a particular type of calendar. The calendar is such that on a normal year it contains N days. Every Mth year on Geekland is known as the "GEEK" year. For example, if M = 5, then years 5, 10, 15, ... are "GEEK" years. A "GEEK" year contains K additional days than a normal year i.e., it contains N + K days. Giv
12 min read
Find Square Root under Modulo p | (When p is product of two primes in the form 4*i + 3)
Given an integer N and an integer P denoting the product of two primes, the task is to find all possible Square Root of N under modulo P if it exists. It is given that P is the product of p1 and p2, where p1 and p2 are prime numbers of the form 4i + 3 where i is any integer. Some examples of such prime numbers are (7, 11, 19, 23, 31). Examples: Inp
15+ min read
Find Square Root under Modulo p | Set 1 (When p is in form of 4*i + 3)
Given a number 'n' and a prime 'p', find square root of n under modulo p if it exists. It may be given that p is in the form for 4*i + 3 (OR p % 4 = 3) where i is an integer. Examples of such primes are 7, 11, 19, 23, 31, ... etc,Examples: Input: n = 2, p = 7Output: 3 or 4Explanation: 3 and 4 both are square roots of 2 under modulo 7 because (3*3)
14 min read
Find Square Root under Modulo p | Set 2 (Shanks Tonelli algorithm)
Given a number ‘n’ and a prime ‘p’, find square root of n under modulo p if it exists. Examples: Input: n = 2, p = 113 Output: 62 62^2 = 3844 and 3844 % 113 = 2 Input: n = 2, p = 7 Output: 3 or 4 3 and 4 both are square roots of 2 under modulo 7 because (3*3) % 7 = 2 and (4*4) % 7 = 2 Input: n = 2, p = 5 Output: Square root doesn't exist We have di
15+ min read
Find power of power under mod of a prime
Given four numbers A, B, C and M, where M is prime number. Our task is to find ABC (mod M).Example: Input : A = 2, B = 4, C = 3, M = 23 Output : 6 43 = 64 so, 2^64(mod 23) = 6 A Naive Approach is to calculate res = BC and then calculate Ares % M by modular exponential. The problem of this approach is that we can't apply directly mod M on BC, so we
7 min read
Article Tags :
Practice Tags :
three90RightbarBannerImg