Search code examples
dictionarygraphdynamic-programmingmemoizationdirected-acyclic-graphs

How does one approach this challenge asked in an Amazon Interview?


I am struggling optimising this past amazon Interview question involving a DAG.

This is what I tried (The code is long and I would rather explain it)-

  1. Basically since the graph is a DAG and because its a transitive relation a simple traversal for every node should be enough.

  2. So for every node I would by transitivity traverse through all the possibilities to get the end vertices and then compare these end vertices to get the most noisy person.

  3. In my second step I have actually found one such (maybe the only one) most noisy person for all the vertices of the traversal in step 2. So I memoize all of this in a mapping and mark the vertices of the traversal as visited.

  4. So I am basically maintaining an adjacency list for the graph, A visited/non visited mapping and a mapping for the output (the most noisy person for every vertex).

  5. In this way by the time I get a query I would not have to recompute anything (in case of duplicate queries).

The above code works but since I cannot test is with testcases it may/may not pass the time limit. Is there a faster solution(maybe using DP) to this. I feel I am not exploiting the transitive and anti symmetric condition enough.

Obviously I am not checking the cases where a person is less wealthy than the current person. But for instance if I have pairs like - (1,2)(1,3)(1,4)...etc and maybe (2,6)(2,7)(7,8),etc then if I am given to find a more wealthy person than 1 I have traverse through every neighbor of 1 and then the neighbor of every neighbor also I guess. This is done only once as I store the results.

Question Part 1

Question Part 2

Edit(Added question Text)-

Rounaq is graduating this year. And he is going to be rich. Very rich. So rich that he has decided to have a structured way to measure his richness. Hence he goes around town asking people about their wealth, and notes down that information. Rounaq notes down the pair (Xi; Yi) if person Xi has more wealth than person Yi. He also notes down the degree of quietness, Ki, of each person. Rounaq believes that noisy persons are a nuisance. Hence, for each of his friends Ai, he wants to determine the most noisy(least quiet) person among those who have wealth more than Ai. Note that "has more wealth than"is a transitive and anti-symmetric relation. Hence if a has more wealth than b, and b has more wealth than c then a has more wealth than c. Moreover, if a has more wealth than b, then b cannot have more wealth than a. Your task in this problem is to help Rounaq determine the most noisy person among the people having more wealth for each of his friends ai, given the information Rounaq has collected from the town. Input First line contains T: The number of test cases Each Test case has the following format:

N

K1 K2 K3 K4 : : : Kn

M

X1 Y1

X2 Y2

. . .

. . .

XM YM

Q

A1

A2

. . .

. . .

AQ

N: The number of people in town

M: Number of pairs for which Rounaq has been able to obtain the wealth information

Q: Number of Rounaq’s Friends

Ki: Degree of quietness of the person i

Xi; Yi: The pairs Rounaq has noted down (Pair of distinct values)

Ai: Rounaq’s ith friend

For each of Rounaq’s friends print a single integer - the degree of quietness of the most noisy person as required or -1 if there is no wealthier person for that friend.


Solution

  • Perform a topological sort on the pairs X, Y. Then iterate from the most wealthy down the the least wealthy, and store the most noisy person seen so far:

    less wealthy    ->    most wealthy
    <- person with lowest K so far <-
    

    Then for each query, binary search the first person with greater wealth than the friend. The value we stored is the most noisy person with greater wealth than the friend.

    UPDATE

    It seems that we cannot rely on the data allowing for a complete topological sort. In this case, traverse sections of the graph that lead from known greatest to least wealth, storing for each person visited the most noisy person seen so far. The example you provided might look something like:

      3 - 5
     /    |
    1 - 2 |
       /  |
      4 --
    

    Traversals:

    1 <- 3 <- 5
    1 <- 2
    4 <- 2
    4 <- 5
    

    (Input)

    2 1
    2 4
    3 1
    5 3
    5 4
    8 2 16 26 16
    

    (Queries and solution)

     3  4  3  5  5 
    16  2 16 -1 -1