 GFG App
Open App Browser
Continue

# Find number of Employees Under every Manager

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 ` `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 > mngrEmpMap,` `    ``map& 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 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 dataset)` `{`   `    ``// A hashmap to store result. It stores count of` `    ``// employees under every employee, the count may by 0` `    ``// also` `    ``map result;`   `    ``// To store reverse of original map, each key will have` `    ``// 0 to multiple values` `    ``unordered_map > 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 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::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 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 result =` `                             ``new` `HashMap();`   `    ``// Driver function` `    ``public` `static` `void` `main(String[] args)` `    ``{` `        ``Map dataSet = ``new` `HashMap();` `        ``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 dataSet)` `    ``{` `        ``// To store reverse of original map, each key will have 0` `        ``// to multiple values` `        ``Map> mngrEmpMap =` `                                  ``new` `HashMap>();`   `        ``// To fill mngrEmpMap, iterate through the given map` `        ``for` `(Map.Entry 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 directReportList = mngrEmpMap.get(mngr);`   `                ``// If 'emp' is the first employee under 'mgr'` `                ``if` `(directReportList == ``null``)` `                ``{` `                    ``directReportList = ``new` `ArrayList();` `                    ``// 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> 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 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)

My Personal Notes arrow_drop_up