Who Reports


// { employee_id, manager_id }
// ( { 2, 1 }, { 3, 1 }, { 4, 2 }, { 5, 7 }, {6, 3 }, { 7, 4 } )

// whoReportsTo( 3 ) --> ( 6 )
// whoReportsTo( 2 ) --> ( 4, 7, 5 )
// { 4, 2 }, { 7, 4 } ==> {7, 4(manger), 2(manger)}

// Graph represented by Adjacency list
public static class Relations {
  // mangerid --> subids
  private Map<Integer, Set<Integer>> subRelations = new HashMap<>();

  public Relations(int[][] relations) {
    for (int i = 0; i < relations.length; i++) {
      manged(relations[i][0], relations[i][1]);
    }
    // if we also want to get the forward relationship, store it as
    // map<int, int>
  }

  public void manged(int empid, int mangerid) {
    Set<Integer> subs = subRelations.get(mangerid);
    if (subs == null) {
      subs = new HashSet<>();
      subRelations.put(mangerid, subs);
    }

    subs.add(empid);
  }

  public Set<Integer> whoReportsToBFS(int mangerid) {
    Set<Integer> mysubs = subRelations.get(mangerid);
    // if (mysubs == null)
    // throw new IllegalArgumentException(mangerid + " doesn't exist");

    // direct subs comes first
    Set<Integer> result = new LinkedHashSet<>();

    if (mysubs == null)
      return result;
    // BFS, but only for the paths that starts with mangerid
    Queue<Integer> queue = new LinkedList<>();
    queue.addAll(mysubs);
    while (!queue.isEmpty()) {
      Integer subid = queue.poll();
      // one empid is only managed by one manager, and there should be
      // no loop
      if (result.contains(subid)) {
        throw new LoopExistException("subid: " + subid);
      }
      result.add(subid);

      if (subRelations.containsKey(subid)) {
        queue.addAll(subRelations.get(subid));
      }
    }
    return result;
  }

  public Set<Integer> whoReportsToDFS(int mangerid) {
    Set<Integer> mysubs = subRelations.get(mangerid);
    // if (mysubs == null)
    // throw new IllegalArgumentException(mangerid + " doesn't exist");

    // direct subs comes first
    Set<Integer> result = new LinkedHashSet<>();

    if (mysubs == null)
      return result;
    // DFS, but only for the paths that starts with mangerid
    LinkedList<Integer> stack = new LinkedList<>();
    stack.addAll(mysubs);
    while (!stack.isEmpty()) {
      Integer subid = stack.pollLast();
      // one empid is only managed by one manager, and there should be
      // no loop
      if (result.contains(subid)) {
        throw new LoopExistException("subid: " + subid);
      }
      result.add(subid);
      if (subRelations.containsKey(subid)) {
        stack.addAll(subRelations.get(subid));
      }
    }
    return result;
  }

  public static void main(String[] args) {
    // { employee_id, manager_id }
    // ( { 2, 1 }, { 3, 1 }, { 4, 2 }, { 5, 7 }, {6, 3 }, { 7, 4 } )
    int[][] arr = new int[][] { { 2, 1 }, { 3, 1 }, { 4, 2 }, { 5, 7 },
        { 6, 3 }, { 7, 4 } };
    Relations relations = new Relations(arr);
    // System.out.println(relations.whoReportsToBFS(2));
    System.out.println(relations.whoReportsToDFS(2));

    // there is loop in the input { 2, 1 }, { 1, 2 }
    arr = new int[][] { { 2, 1 }, { 1, 2 }, { 3, 1 }, { 4, 2 },
        { 5, 7 }, { 6, 3 }, { 7, 4 } };
    relations = new Relations(arr);
    System.out.println(relations.whoReportsToDFS(2));
  }
}

Labels

adsense (5) Algorithm (69) Algorithm Series (35) Android (7) ANT (6) bat (8) Big Data (7) Blogger (14) Bugs (6) Cache (5) Chrome (19) Code Example (29) Code Quality (7) Coding Skills (5) Database (7) Debug (16) Design (5) Dev Tips (63) Eclipse (32) Git (5) Google (33) Guava (7) How to (9) Http Client (8) IDE (7) Interview (88) J2EE (13) J2SE (49) Java (186) JavaScript (27) JSON (7) Learning code (9) Lesson Learned (6) Linux (26) Lucene-Solr (112) Mac (10) Maven (8) Network (9) Nutch2 (18) Performance (9) PowerShell (11) Problem Solving (11) Programmer Skills (6) regex (5) Scala (6) Security (9) Soft Skills (38) Spring (22) System Design (11) Testing (7) Text Mining (14) Tips (17) Tools (24) Troubleshooting (29) UIMA (9) Web Development (19) Windows (21) xml (5)