Google Interview Question for Senior Software Development Engineers


Country: United States
Interview Type: In-Person




Comment hidden because of low score. Click to expand.
0
of 0 vote

Simple Solution
1.) Start with all keys in dictionary.
2.) For each key do a BFS search , putting groups in a hashset of used group , so that you don't queue them again in BFS. When you encounter a user in queue just add it to group list , when you encounter a group put group in queue for going deep.

- Anonymous July 23, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

why BFS instead of DFS? I would thinking dfs would suffice since we are talking about finding children and parents of each group

- enok July 23, 2015 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

This can accomplished using 2 stack + dfs + visited flag array. Idea is as you go down the graph you build the memberOf groups and as you trace back up you build the members groups for the Group you are traversing.

a. Iterator over hashmap
b. For each entry do following
Invariant is for Groups in parent stack you have computed memberOf groups. When you pop groups from parent stack you will be going back up and computing members group.
1. initial 2 stack. a parent and a child stack. initial parent stack with G4 and child with its children i.e G1. Memberof Parent G4 are none so nthing to do here
2. When you pop a element from child stack , create a new object MyGroups. Get the parent of child (G4, maintain 2 hashmaps for Parent to child and child to parent mapping). Mark it as visited and add users to MyGroup's user list.
3. Add parent (G4) to memberOf of child (G1). Add memberOFs of parent(G4) to membersOf child as well. Push this child to parent stack.
4. Update parent-child mapping and child-parent mapping.
5. Get the children of G1 from input dictionary and push them on child stack.
6. Continue steps 2-5 till child stack is empty.
7. Child stack is now empty.
8. Pop element from parent stack . Note the leaf of the graph will be at top now.
9. Get it's child from the parent-child mapping we build when we worked on child stack.
10. add the child to member of this group's MyGroup object. Get the child's member list and also add it to this group's MyGroup object.
Node. if its a leaf the there won't be any entry the the parent-child mapping unless it a cycle.
11. Continue poppping elements from parent stack and repeat steps 9-10 till parent stack is empty.
c. Once we have execute step b for all entries in input dictionary return our build list of MyGroup

- um01 July 23, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Sounds like a good algo. Do you mind sharing the actual code ?

- enok July 23, 2015 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

This sounds like a good plan. Do you have pseudo code for this approach? Would love to see how the algorithm looks in real code

- enok July 23, 2015 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Was this question asked in an in a phone interview or an onsite interview?

- nik July 23, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Was this question asked in an in a phone interview or an onsite interview?

- nik July 23, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

public static List<MyGroup> FindMembers(Dictionary<string, HashSet<string>> groupMembers)
        {
            Dictionary<string, MyGroup> groups = new Dictionary<string, MyGroup>();
            List<KeyValuePair<string, string>> map = new List<KeyValuePair<string, string>>();
            foreach (var groupName in groupMembers.Keys)
            {
                groups.Add(groupName, new MyGroup(groupName));
                foreach (var memberName in groupMembers[groupName])
                {
                    map.Add(new KeyValuePair<string, string>(groupName, memberName));
                }
            }
            foreach (var pair in map)
            {
                var parent = groups[pair.Key];
                if (groups.ContainsKey(pair.Value))
                {
                    var child = groups[pair.Value];
                    parent.Members.Add(pair.Value, child);
                    child.MemberOf.Add(pair.Key, parent);
                }
                else
                {
                    parent.Users.Add(pair.Value);
                }
            }
            return groups.Values.ToList();
        }

- Anonymous July 24, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

it will work

- pm July 25, 2015 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Not sure whether this will work not. Do you add the indirect parents/children?

- wwu August 02, 2015 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

It seems you don't take indirect parents/children into consideration.

- liuweizi610 August 21, 2015 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

public static List<MyGroup> FindMembers(Dictionary<string, HashSet<string>> groupMembers)
        {
            Dictionary<string, MyGroup> groups = new Dictionary<string, MyGroup>();
            List<KeyValuePair<string, string>> map = new List<KeyValuePair<string, string>>();
            foreach (var groupName in groupMembers.Keys)
            {
                groups.Add(groupName, new MyGroup(groupName));
                foreach (var memberName in groupMembers[groupName])
                {
                    map.Add(new KeyValuePair<string, string>(groupName, memberName));
                }
            }
            foreach (var pair in map)
            {
                var parent = groups[pair.Key];
                if (groups.ContainsKey(pair.Value))
                {
                    var child = groups[pair.Value];
                    parent.Members.Add(pair.Value, child);
                    child.MemberOf.Add(pair.Key, parent);
                }
                else
                {
                    parent.Users.Add(pair.Value);
                }
            }
            return groups.Values.ToList();
        }

- je July 24, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

public static List<MyGroup> FindMembers(Dictionary<string, HashSet<string>> groupMembers)
        {
            Dictionary<string, MyGroup> groups = new Dictionary<string, MyGroup>();
            List<KeyValuePair<string, string>> map = new List<KeyValuePair<string, string>>();
            foreach (var groupName in groupMembers.Keys)
            {
                groups.Add(groupName, new MyGroup(groupName));
                foreach (var memberName in groupMembers[groupName])
                {
                    map.Add(new KeyValuePair<string, string>(groupName, memberName));
                }
            }
            foreach (var pair in map)
            {
                var parent = groups[pair.Key];
                if (groups.ContainsKey(pair.Value))
                {
                    var child = groups[pair.Value];
                    parent.Members.Add(pair.Value, child);
                    child.MemberOf.Add(pair.Key, parent);
                }
                else
                {
                    parent.Users.Add(pair.Value);
                }
            }
            return groups.Values.ToList();

}

- Anonymous July 24, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

public static List<MyGroup> FindMembers(Dictionary<string, HashSet<string>> groupMembers)
        {
            Dictionary<string, MyGroup> groups = new Dictionary<string, MyGroup>();
            List<KeyValuePair<string, string>> map = new List<KeyValuePair<string, string>>();
            foreach (var groupName in groupMembers.Keys)
            {
                groups.Add(groupName, new MyGroup(groupName));
                foreach (var memberName in groupMembers[groupName])
                {
                    map.Add(new KeyValuePair<string, string>(groupName, memberName));
                }
            }
            foreach (var pair in map)
            {
                var parent = groups[pair.Key];
                if (groups.ContainsKey(pair.Value))
                {
                    var child = groups[pair.Value];
                    parent.Members.Add(pair.Value, child);
                    child.MemberOf.Add(pair.Key, parent);
                }
                else
                {
                    parent.Users.Add(pair.Value);
                }
            }
            return groups.Values.ToList();
        }

- Je July 24, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

public class GroupMembership {

	public class Group {
		public String Name;
		public List<Group> memberOf;
		public List<Group> members;
		public List<String> users;
		
		public Group(String name){
			this.Name = name;
			memberOf = new ArrayList<Group>();
			members = new ArrayList<Group>();
			users = new ArrayList<String>();

		}

		public void printMembers(){
			for(int i=0;i< this.members.size();i++){
				System.out.print(this.members.get(i).Name+((i<this.members.size()-1)?", ":""));
			}
			System.out.println();
		}

		public void printParents(){
			for(int i=0;i< this.memberOf.size();i++){
				System.out.print(memberOf.get(i).Name+((i<this.memberOf.size()-1)?", ":""));
			}
			System.out.println();	
		}

		public void printUsers(){
			for(int i=0;i< this.users.size();i++){
				System.out.print(users.get(i)+((i<this.users.size()-1)?", ":""));
			}
			System.out.println();
		}
	}
	
	public HashMap<String, Group> findMembership(HashMap<String, HashSet<String>> groups){
		
		HashMap<String, Group> visitedGroups = new HashMap<String, Group>();
		
		Set<String> keys = groups.keySet();
		Iterator<String> keysItr = keys.iterator();
		while(keysItr.hasNext()){
			
			//get the group name 
			String parentGroupName = keysItr.next();
			
			if(!visitedGroups.containsKey(parentGroupName)){
				Group newGroup = new Group(parentGroupName);
				visitedGroups.put(parentGroupName,newGroup);
			}
			
			Group mainGroup  = visitedGroups.get(parentGroupName);

			HashSet<String> ownGroups = groups.get(parentGroupName);
			Iterator<String> itr = ownGroups.iterator();
			while(itr.hasNext()){
				String currGroupName  = itr.next();

				if(currGroupName.startsWith("U")){
					mainGroup.users.add(currGroupName);
					continue;
				}

				if(visitedGroups.containsKey(currGroupName)){
					
					if(currGroupName == parentGroupName){
						visitedGroups.put(parentGroupName,mainGroup);
						mainGroup  = visitedGroups.get(parentGroupName);
					}
					
					Group gp = visitedGroups.get(currGroupName);
					gp.memberOf.add(visitedGroups.get(parentGroupName));
					visitedGroups.put(currGroupName,gp);
					
						
					mainGroup.members.add(gp);
				}else{
					Group newGroup = new Group(currGroupName);
					newGroup.memberOf.add(mainGroup);
					visitedGroups.put(currGroupName,newGroup);
					mainGroup.members.add(newGroup);
				}
			}

			visitedGroups.put(parentGroupName,mainGroup);			
		}
		
		return visitedGroups;
	}

	public static void main(String [] args){
		
		GroupMembership gm = new GroupMembership();

		HashMap<String, HashSet<String>> groups = new HashMap<String, HashSet<String>>();
		HashSet<String> temp1 = new HashSet<String>();
		temp1.add("U1");temp1.add("G1");
		groups.put("G4", temp1);
		
		HashSet<String> temp2 = new HashSet<String>();
		temp2.add("G2");temp2.add("G3");
		groups.put("G1", temp2);
		
		HashSet<String> temp3 = new HashSet<String>();
		temp3.add("G3");temp3.add("G5");
		groups.put("G3", temp3);
		
		HashSet<String> temp4 = new HashSet<String>();
		temp4.add("U2");temp4.add("G4");
		groups.put("G2", temp4);
		
		HashSet<String> temp5 = new HashSet<String>();
		temp5.add("U2");temp5.add("G6");
		groups.put("G5", temp5);
				
		HashSet<String> temp6 = new HashSet<String>();
		temp6.add("U3");
		groups.put("G6", temp6);
		
		
		HashMap<String, Group> processedGroups = gm.findMembership(groups);

		Set<String> keys = processedGroups.keySet();
		Iterator<String> keysItr  = keys.iterator(); 
		
		while(keysItr.hasNext()){
			
			Group currGroup = processedGroups.get(keysItr.next());
			System.out.println("Name: "+currGroup.Name);
			System.out.print("Member Groups: ");
			currGroup.printMembers();
			System.out.print("Member Of: ");
			currGroup.printParents();
			System.out.print("Users: ");
			currGroup.printUsers();
			System.out.println();
		}
	}
		

}

- akella.mahesh July 24, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

package main.Questions.ID5191526374178816;

import java.util.*;

public class Members {

    Map<String, MyGroup> groupList = new HashMap<String, MyGroup>();

    public Map<String, MyGroup> getMyGroupsList(Map<String, HashSet<String>> groupMembers) {
        for (Map.Entry<String, HashSet<String>> groupMember : groupMembers.entrySet()) {
            MyGroup myGroup = createMyGroup(groupMember.getKey());
            findMyGroupMembers(groupMembers, groupMember, myGroup);

        }
        return groupList;
    }

    private void findMyGroupMembers(Map<String, HashSet<String>> groupMembers, Map.Entry<String, HashSet<String>> groupMember, MyGroup myGroup) {
        Queue<HashSet<String>> subGroupMembersQueue = new LinkedList<HashSet<String>>();
        HashSet<String> visited = new HashSet<String>();

        subGroupMembersQueue.add(groupMember.getValue());

        while (subGroupMembersQueue.size() > 0) {

            HashSet<String> subGroupMembers = subGroupMembersQueue.remove();

            for (String subGroupMember : subGroupMembers) {
                if (isaGroup(groupMembers, subGroupMember)) {
                    if (!visited.contains(subGroupMember)) {
                        visited.add(subGroupMember);
                        subGroupMembersQueue.add(groupMembers.get(subGroupMember));
                    }

                    MyGroup subMyGroup = createMyGroup(subGroupMember);
                    subMyGroup.MemberOf.put(myGroup.Identity, myGroup);
                    groupList.put(subMyGroup.Identity, subMyGroup);
                    myGroup.Members.put(subMyGroup.Identity, subMyGroup);
                } else {
                    myGroup.Users.add(subGroupMember);
                }
            }

        }
        groupList.put(myGroup.Identity, myGroup);
    }

    private boolean isaGroup(Map<String, HashSet<String>> groupMembers, String subGroupMember) {
        return groupMembers.containsKey(subGroupMember);
    }

    private MyGroup createMyGroup(String key) {
        if (!groupList.containsKey(key)) {
            MyGroup myGroup = new MyGroup(key);
            groupList.put(key, myGroup);
        }
        return groupList.get(key);
    }
}

git.io/vOnjm -- source
git.io/vOnj8 -- test

- inadram August 02, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

A long solution..

Do 2 dfs for parents and children.

public static class Group{
        public String identity;
        public HashMap<String, Group> memberOf;
        public HashMap<String, Group> members;
        public HashSet<String> users;
        public Group(String name){
            identity = name;
            memberOf = new HashMap<String, Group>();
            members = new HashMap<String, Group>();
            users = new HashSet<String>();
        }
    }

    public static class Node{
        String identity;
        List<Node> child;
        int state;
        List<Node> parent;
        public Node(String name){
            identity = name;
            child = new ArrayList<Node>();
            state = 0;
            this.parent = new ArrayList<Node>();
        }
    }
    public static List<Group> findGroup(HashMap<String, HashSet<String>>
                                                groupMembers){
        List<Group> result = new ArrayList<Group>();

        HashMap<String, Node> nodeHashMap = new HashMap<String, Node>();

        for(Map.Entry<String, HashSet<String>> entry : groupMembers.entrySet()){
            String name = entry.getKey();
            HashSet<String> member = entry.getValue();
            Node node;
            if(nodeHashMap.containsKey(name)){
                node = nodeHashMap.get(name);
            }else{
                node = new Node(name);
                nodeHashMap.put(name, node);
            }
            for(String elem : member){
                Node child;
                if(nodeHashMap.containsKey(elem)){
                    child = nodeHashMap.get(elem);
                }else{
                    child = new Node(elem);
                    nodeHashMap.put(elem, child);
                }
                child.parent.add(node);
                node.child.add(child);
            }
        }
        HashMap<String, Group> groupHashMap = new HashMap<String, Group>();
        for(Map.Entry<String, Node> entry : nodeHashMap.entrySet()) {
            Group group = new Group(entry.getKey());
            groupHashMap.put(entry.getKey(), group);
            result.add(group);
        }

        for(Map.Entry<String, Node> entry : nodeHashMap.entrySet()){
            Node node = entry.getValue();
            if(node.state == 2){
                Group g = groupHashMap.get(node.identity);
                if(!g.members.isEmpty() && !g.users.isEmpty())    continue;
                for(Node nd : node.child){
                    String ndId = nd.identity;
                    if(ndId.startsWith("G")){
                        g.members.put(ndId, groupHashMap.get(ndId));
                    }else{
                        g.users.add(ndId);
                    }
                }
                continue;
            }
            Stack<Node> nodeStack = new Stack<Node>();
            nodeStack.add(node);
            while(!nodeStack.isEmpty()){
                Node curNode = nodeStack.peek();
                if(curNode.state == 1){
                    curNode.state = 2;
                    Set<String> allchild = new HashSet<String>();

                    for(Node curNodeChild : curNode.child){
                        allchild.add(curNodeChild.identity);
                        for(Node curNodeGrandChild : curNodeChild.child){
                            allchild.add(curNodeGrandChild.identity);
                        }
                    }
                    curNode.child.clear();
                    for(String id : allchild){
                        curNode.child.add(nodeHashMap.get(id));
                    }

                    nodeStack.pop();
                    continue;
                }
                curNode.state = 1;
                List<Node> child = curNode.child;
                for(Node childNode : child){
                    if(childNode.state == 1){
                        return null;
                    }else{
                        nodeStack.push(childNode);
                    }
                }
            }
            Group g = groupHashMap.get(node.identity);
            for(Node nd : node.child){
                String ndId = nd.identity;
                if(ndId.startsWith("G")){
                    g.members.put(ndId, groupHashMap.get(ndId));
                }else{
                    g.users.add(ndId);
                }
            }
        }

        for(Map.Entry<String, Node> entry : nodeHashMap.entrySet()) {
            entry.getValue().state = 0;
        }

        for(Map.Entry<String, Node> entry : nodeHashMap.entrySet()) {
            Node node = entry.getValue();
            if (node.state == 2) {
                Group g = groupHashMap.get(node.identity);
                if (!g.memberOf.isEmpty()) continue;
                for (Node nd : node.parent) {
                    String ndId = nd.identity;
                    g.memberOf.put(ndId, groupHashMap.get(ndId));
                }
                continue;
            }
            Stack<Node> nodeStack = new Stack<Node>();
            nodeStack.add(node);
            while (!nodeStack.isEmpty()) {
                Node curNode = nodeStack.peek();
                if (curNode.state == 1) {
                    curNode.state = 2;
                    Set<String> allparent = new HashSet<String>();

                    for (Node curNodeParent : curNode.parent) {
                        allparent.add(curNodeParent.identity);
                        for (Node curNodeGrandParent : curNodeParent.parent) {
                            allparent.add(curNodeGrandParent.identity);
                        }
                    }
                    curNode.parent.clear();
                    for (String id : allparent) {
                        curNode.parent.add(nodeHashMap.get(id));
                    }

                    nodeStack.pop();
                    continue;
                }
                curNode.state = 1;
                List<Node> parent = curNode.parent;
                for (Node parentNode : parent) {
                    if (parentNode.state == 1) {
                        return null;
                    } else {
                        nodeStack.push(parentNode);
                    }
                }
            }
            Group g = groupHashMap.get(node.identity);
            for (Node nd : node.parent) {
                String ndId = nd.identity;
                g.memberOf.put(ndId, groupHashMap.get(ndId));
            }
        }
        return result;
    }

- wwu August 02, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

/* package whatever; // don't place package name! */

import java.util.*;
import java.lang.*;
import java.io.*;

/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{
	public static void main (String[] args) throws java.lang.Exception
	{
		// your code goes here
		HashMap<String, HashSet<String>> groupMembers = new HashMap<String, HashSet<String>>()
		{{
		    put("G4", new HashSet<String>() {{ add("U1"); add("G1"); }});	
		    put("G1", new HashSet<String>() {{ add("G2"); add("G3"); add("G6"); }});	
		    put("G3", new HashSet<String>() {{ add("G3"); add("G5"); }});	
		    put("G2", new HashSet<String>() {{ add("G4"); add("U2"); }});	
		    put("G5", new HashSet<String>() {{ add("U2"); add("G6"); }});	
		    put("G6", new HashSet<String>() {{ add("U3"); }});	
		}};
		
		ArrayList<Group> result = FindMembers(groupMembers);
		for (Group g : result)
		{
			System.out.println(g.toString());
		}
	}
	
	public static ArrayList<Group> FindMembers(HashMap<String, HashSet<String>> groupMembers)
	{
		if (groupMembers == null) { throw new IllegalArgumentException("groupMembers"); }

		if (groupMembers.size() == 0) { return new ArrayList<Group>(); }
		
		HashSet<String> visited = new HashSet<String>(); // keep track of which group has been visited
		HashMap<String, Member> members = new HashMap<String, Member>(); // for fast member lookup
		
		// Performing a breadth-first traversal using a Queue and a loop
		Queue<Member> queue = new LinkedList<Member>();
		
		for (String key : groupMembers.keySet())
		{
			Group group = new Group(key);
			queue.offer(group);
			members.put(key, group);
		}
		
		while (!queue.isEmpty())
		{
			Member member = queue.poll();
			if (member instanceof Group)
			{
				Group group = (Group)member;

				String memberName = member.getName();
				if (!visited.contains(memberName))
				{
					visited.add(memberName);
				
					// Now process the children
					HashSet<String> children = groupMembers.get(memberName);
					for (String c : children)
					{
						Member m = members.get(c);
						if (m != null && m instanceof Group)
						{
							Group g = (Group)m;
							g.addMemberOf(group);
							group.addMember(g);
							queue.offer(g);
						}
						else // user
						{
							User u = m == null ? new User(c) : (User)m;
							group.addMember(u);
						}

					}
				}
			}
		}
		
		ArrayList<Group> results = new ArrayList<Group>();
		for (Member m : members.values())
		{
			if (m instanceof Group)
			{
				results.add((Group)m);
			}
		}
		return results;
	}
	
	private static class Member
	{
		private String name;

		protected Member(String name)
		{
			if (name == null || name.length() == 0)
			{
				throw new IllegalArgumentException("name");
			}
			
			this.name = name;
		}
		
		public String getName() { return this.name; }
		
		public String toString() { return this.getName(); }
	}
	
	private static class User extends Member
	{
		public User(String name)
		{
			super(name);
		}
	}
	
	private static class Group extends Member
	{
		private HashMap<String, Group> memberOf = new HashMap<String, Group>();
		private HashMap<String, Member> members = new HashMap<String, Member>();
		
		public Group(String name)
		{
			super(name);
		}

		public HashMap<String, Group> getMemberOf() { return this.memberOf; }
		
		public HashMap<String, Member> getMembers() { return this.members; }
		
		public void addMember(Member m)
		{
			if (!this.members.containsKey(m.getName()))
			{
				this.members.put(m.getName(), m);
			}
		}
		
		public void addMemberOf(Group g)
		{
			if (!this.memberOf.containsKey(g.getName()))
			{
				this.memberOf.put(g.getName(), g);
			}
		}
		public String toString()
		{
			StringBuilder sb = new StringBuilder();
			sb.append("Group: " + this.getName() + "\n");
			sb.append("MemberOf: ");
			for (Group g : this.getMemberOf().values())
			{
				sb.append(g.getName() + ", ");
			}
			sb.append("Members: ");
			for (Member m : this.getMembers().values())
			{
				sb.append(m.getName() + ", ");
			}
			
			return sb.toString();
		}
	}
}

Success time: 0.11 memory: 320512 signal:0
Group: G1
MemberOf: G4, Members: G2, G3, G6,
Group: G2
MemberOf: G1, Members: G4, U2,
Group: G3
MemberOf: G1, G3, Members: G3, G5,
Group: G4
MemberOf: G2, Members: G1, U1,
Group: G5
MemberOf: G3, Members: U2, G6,
Group: G6
MemberOf: G1, G5, Members: U3,

- nghi1129 April 06, 2016 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

c++
Step 1: Build base MyGroup object map
Step 2: For each object, Search Graph (DPS) , building members, memberOf and users
Step 3: Build output vector

#include <iostream>
#include "vector"
#include "map"
#include "stack"
#include "queue"
#include "string"

using namespace std;

typedef map<string, class MyGroup *> groupObjectMap;
typedef vector<class MyGroup *> groupObjectList;

typedef vector<string> ulist;

class MyGroup 
{
	public:
	string name;
	groupObjectMap memberOf;
	groupObjectMap members;
	ulist users;
} ;

typedef map<string, vector<string>> groupsHash;

// build intersection_list list
void searchDFSIterative(string node, groupsHash groupMembers, groupObjectMap &objects, MyGroup *object)
{
	stack<string> mystack;
	map<string, bool> visited;

	// Base Case, tree is empty
	if (node.empty())
		return;

	mystack.push(node);

	while (!mystack.empty())
	{
		node = mystack.top();
		mystack.pop();

		if (visited.find(node) == visited.end())
		{
			visited[node] = true;

			if (object->name != node)
			{
				// add visited node to me (excluding me)
				object->members[node] = objects[node];

				// add me to visited node
				objects[node]->memberOf[object->name] = object;
			}

			for (auto name : groupMembers[node])
			{
				if (name.substr(0, 1) == string("U"))
				{
					if (find(object->users.begin(), object->users.end(), name) == object->users.end())
					{
						object->users.push_back(name);
					}
				}
				else
				{
					mystack.push(name); 
				}
			}

		}
	}
}

vector<MyGroup *>FindMembers(groupsHash groupMembers)
{
	groupObjectMap groupObjects;
	vector<MyGroup *> output;

	// Build the parents
	for (auto grouppair : groupMembers)
	{
		// Each of these is a node/root with members
		MyGroup *object = new MyGroup();
		object->name = grouppair.first;
		groupObjects[grouppair.first] = object;
	}

	for (auto objectpair : groupObjects)
	{
		// Each of these is a node/root with members
		MyGroup *object = objectpair.second;
		
		searchDFSIterative(objectpair.first, groupMembers, groupObjects, object);
	}

	for (auto grouppair : groupObjects)
	{
		output.push_back(grouppair.second);
	}

	for (auto group : output)
	{
		cout << "Group " << group->name << endl;
		cout << "  memberOf: ";
		for (auto memberpair : group->memberOf)
		{
			cout << memberpair.first << " ";
		}
		cout << endl;
		cout << "   members: ";
		for (auto memberpair : group->members)
		{
			cout << memberpair.first << " ";
		}
		cout << endl;
		cout << "     users: ";
		for (auto user : group->users)
		{
			cout << user << " ";
		}
		cout << endl;
	}

	return output;
}

int main(int argc, char **argv)
{
	groupsHash groups;
	groups["G4"] = { "U1", "G1" }; 
	groups["G1"] = { "G2", "G3", "G6" };
	groups["G3"] = { "G3", "G5" };
	groups["G2"] = { "G4", "U2" };
	groups["G5"] = { "U2", "G6" };
	groups["G6"] = { "U3" };

	FindMembers(groups);
}

- drs April 11, 2017 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

c++ answer
Step 1: Build map of base group objects
Step 2: for each base object, DFS search to build members, memberof and users
Step 3: Build output

#include <iostream>
#include "vector"
#include "map"
#include "stack"
#include "queue"
#include "string"

using namespace std;

typedef map<string, class MyGroup *> groupObjectMap;
typedef vector<class MyGroup *> groupObjectList;

typedef vector<string> ulist;

class MyGroup 
{
	public:
	string name;
	groupObjectMap memberOf;
	groupObjectMap members;
	ulist users;
} ;

typedef map<string, vector<string>> groupsHash;

// build intersection_list list
void searchDFSIterative(string node, groupsHash groupMembers, groupObjectMap &objects, MyGroup *object)
{
	stack<string> mystack;
	map<string, bool> visited;

	// Base Case, tree is empty
	if (node.empty())
		return;

	mystack.push(node);

	while (!mystack.empty())
	{
		node = mystack.top();
		mystack.pop();

		if (visited.find(node) == visited.end())
		{
			visited[node] = true;

			if (object->name != node)
			{
				// add visited node to me (excluding me)
				object->members[node] = objects[node];

				// add me to visited node
				objects[node]->memberOf[object->name] = object;
			}

			for (auto name : groupMembers[node])
			{
				if (name.substr(0, 1) == string("U"))
				{
					if (find(object->users.begin(), object->users.end(), name) == object->users.end())
					{
						object->users.push_back(name);
					}
				}
				else
				{
					mystack.push(name); 
				}
			}

		}
	}
}

vector<MyGroup *>FindMembers(groupsHash groupMembers)
{
	groupObjectMap groupObjects;
	vector<MyGroup *> output;

	// Build the parents
	for (auto grouppair : groupMembers)
	{
		// Each of these is a node/root with members
		MyGroup *object = new MyGroup();
		object->name = grouppair.first;
		groupObjects[grouppair.first] = object;
	}

	for (auto objectpair : groupObjects)
	{
		// Each of these is a node/root with members
		MyGroup *object = objectpair.second;
		
		searchDFSIterative(objectpair.first, groupMembers, groupObjects, object);
	}

	for (auto grouppair : groupObjects)
	{
		output.push_back(grouppair.second);
	}

	for (auto group : output)
	{
		cout << "Group " << group->name << endl;
		cout << "  memberOf: ";
		for (auto memberpair : group->memberOf)
		{
			cout << memberpair.first << " ";
		}
		cout << endl;
		cout << "   members: ";
		for (auto memberpair : group->members)
		{
			cout << memberpair.first << " ";
		}
		cout << endl;
		cout << "     users: ";
		for (auto user : group->users)
		{
			cout << user << " ";
		}
		cout << endl;
	}

	return output;
}

int main(int argc, char **argv)
{
	groupsHash groups;
	groups["G4"] = { "U1", "G1" }; 
	groups["G1"] = { "G2", "G3", "G6" };
	groups["G3"] = { "G3", "G5" };
	groups["G2"] = { "G4", "U2" };
	groups["G5"] = { "U2", "G6" };
	groups["G6"] = { "U3" };

	FindMembers(groups);
}

Group G1
memberOf: G2 G4
members: G2 G3 G4 G5 G6
users: U3 U2 U1
Group G2
memberOf: G1 G4
members: G1 G3 G4 G5 G6
users: U2 U1 U3
Group G3
memberOf: G1 G2 G4
members: G5 G6
users: U2 U3
Group G4
memberOf: G1 G2
members: G1 G2 G3 G5 G6
users: U1 U3 U2
Group G5
memberOf: G1 G2 G3 G4
members: G6
users: U2 U3
Group G6
memberOf: G1 G2 G3 G4 G5
members:
users: U3

- drs April 11, 2017 | Flag Reply


Add a Comment
Name:

Writing Code? Surround your code with {{{ and }}} to preserve whitespace.

Books

is a comprehensive book on getting a job at a top tech company, while focuses on dev interviews and does this for PMs.

Learn More

Videos

CareerCup's interview videos give you a real-life look at technical interviews. In these unscripted videos, watch how other candidates handle tough questions and how the interviewer thinks about their performance.

Learn More

Resume Review

Most engineers make critical mistakes on their resumes -- we can fix your resume with our custom resume review service. And, we use fellow engineers as our resume reviewers, so you can be sure that we "get" what you're saying.

Learn More

Mock Interviews

Our Mock Interviews will be conducted "in character" just like a real interview, and can focus on whatever topics you want. All our interviewers have worked for Microsoft, Google or Amazon, you know you'll get a true-to-life experience.

Learn More