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;
int populateResultUtil(
string mngr,
unordered_map<string, vector<string> > mngrEmpMap,
map<string, int >& result)
{
int count = 0;
if (mngrEmpMap.find(mngr) == mngrEmpMap.end()) {
result.insert({ mngr, 0 });
return 0;
}
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;
}
void populateResult(unordered_map<string, string> dataset)
{
map<string, int > result;
unordered_map<string, vector<string> > mngrEmpMap;
for ( auto d : dataset) {
string emp = d.first;
string mngr = d.second;
if (emp != mngr)
{
if (mngrEmpMap.find(mngr) == mngrEmpMap.end()) {
vector<string> directReportList;
directReportList.push_back(emp);
mngrEmpMap[mngr] = directReportList;
}
else {
mngrEmpMap[mngr].push_back(emp);
}
}
}
for ( auto d : dataset) {
populateResultUtil(d.first, mngrEmpMap, result);
}
map<string, int >::iterator itr;
auto end = result.end();
end--;
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;
}
|
Java
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class NumberEmployeeUnderManager
{
static Map<String,Integer> result =
new HashMap<String, Integer>();
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);
}
private static void populateResult(Map<String, String> dataSet)
{
Map<String, List<String>> mngrEmpMap =
new HashMap<String, List<String>>();
for (Map.Entry<String,String> entry: dataSet.entrySet())
{
String emp = entry.getKey();
String mngr = entry.getValue();
if (!emp.equals(mngr))
{
List<String> directReportList = mngrEmpMap.get(mngr);
if (directReportList == null )
{
directReportList = new ArrayList<String>();
mngrEmpMap.put(mngr, directReportList);
}
directReportList.add(emp);
}
}
for (String mngr: dataSet.keySet())
populateResultUtil(mngr, mngrEmpMap);
}
private static int populateResultUtil(String mngr,
Map<String, List<String>> mngrEmpMap)
{
int count = 0 ;
if (!mngrEmpMap.containsKey(mngr))
{
result.put(mngr, 0 );
return 0 ;
}
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):
d = dict ()
for pair in t:
if (pair[ 0 ] = = pair[ 1 ]):
continue
if pair[ 0 ] not in d:
d[pair[ 0 ]] = []
if pair[ 1 ] not in d:
d[pair[ 1 ]] = [pair[ 0 ]]
else :
d[pair[ 1 ]].append(pair[ 0 ])
c = dict ()
for manager in d:
c[manager] = len (d[manager])
for employee in d[manager]:
c[manager] + = len (d[employee])
print ( "{} : {}" . format (manager,c[manager]))
if __name__ = = "__main__" :
t = (( "A" , "C" ),( "B" , "C" ),( "C" , "F" ),( "D" , "E" ),( "E" , "F" ),( "F" , "F" ))
obj = Solution()
obj.assignAndPrint(t)
|
C#
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))
{
result[mngr] = 0;
return 0;
}
else if (result.ContainsKey(mngr))
{
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 >>();
foreach ( var d in dataset)
{
string emp = d.Key;
string mngr = d.Value;
if (emp != mngr)
{
if (!mngrEmpMap.ContainsKey(mngr))
{
List< string > directReportList = new List< string >();
directReportList.Add(emp);
mngrEmpMap[mngr] = directReportList;
}
else
{
mngrEmpMap[mngr].Add(emp);
}
}
}
foreach ( var d in dataset)
{
PopulateResultUtil(d.Key, mngrEmpMap, result);
}
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
let result = new Map();
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);
}
function populateResult(dataSet) {
let mngrEmpMap = new Map();
for (let [emp, mngr] of dataSet) {
if (emp !== mngr) {
let directReportList = mngrEmpMap.get(mngr);
if (directReportList === undefined) {
directReportList = [];
mngrEmpMap.set(mngr, directReportList);
}
directReportList.push(emp);
}
}
for (let mngr of dataSet.keys()) {
populateResultUtil(mngr, mngrEmpMap);
}
}
function populateResultUtil(mngr, mngrEmpMap) {
let count = 0;
if (!mngrEmpMap.has(mngr)) {
result.set(mngr, 0);
return 0;
}
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;
}
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)
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!