Amazon Interview Question
SDE1sCountry: India
Interview Type: In-Person
@urik:
2 lost to 4
2 lost to 5
5 lost to 4
So winners are 5 4 in the order.
So now (2 lost to 4) 5 2 4 in order.
But this order means 5 lost to 2 which is wrong.
Correct order should be 2 5 4 no?
Can we try this using Graph?
Lets create a graph where Nodes represent people (N nodes).
A directed edge from A to B means that A has defeated B.
After such a graph is created, apply Topological sort.
This also raises a concern for the last element to be added to the queue. Does it mean that last element of the queue hasn't defeated anyone?
Yes you can model the situation with a directed graph (a, b) denoting a beat b.
But it's not necessarily a DAG as, for example, 1 beat 2, 2 beat 3, 3 beat 1.
[1, 2, 3] would be a valid result. Maybe I'm missing something on first look.
But, backtracking is roughly equal to DFS on directed graphs...
Everything turns out slick if we keep a "I beat all these people" list for each person (adj list), and strip out the direct. graph model to the bare minimum. I think backtracking does this?
Maybe there is a more slick way.
Using graph ? Yes.
However this is a completed graph, so it is highly likely to have cycle so topological ordering doest not work. I think you guys recognize wrong problem. The order of the vertices satisfied the requirement form a "Hamiltonian Path" on the complete graph. So any algorithm return hamiltonian path on winning graph should give you the answers
Frenz i have given a DP answer please chek it i have checked it extensively and it works for me
@ LinhHA05 why there is a -ive vote on your solution? Hamiltonian path of the winning graph indeed will give the order. Am I missing something?
I believe you can still use pure DFS approach even though it is not a DAG. You won't get topological sorting (does not exists because of the cycles), but you would get an order in which each person won over the previous one.
@LinhHA05, I said it's not necessarily a DAG == "no top. sort."
@OP
A lot of these "graph like" problems really should state clearly if the underlying query structure is adjList like or adjMatrix like.
@pxe: thank for recognizing my solution. I have many down-vote that I have no clue, but i think it is not important if someone think my answer is useful
@Urik Lagnes: I just want to say that the problem is the problem of finding Hamiltonian path, it is so famous that I don't think it is necessary to show how we do it. Of course if you know how to find Hamiltonian path faster on the complete graph you can show how to do it.
HI Guys I have found a dynamic programming solution to this problem.
I will first discuss the algorithm and then I will give the program for solution.
So to start with this. We will manipulate the array that is we have to start by checkin each and every combination of all the numbers.
So input for me would be a square matrix of size nXn which will have value 1 if i has one over j and 0 if i has lost from j . we can also assume a function which return one if i wins over j and o if i loses over j.
1. Instialize an array of size n with a[i]=1 which will represent our final exam.
2.The base case for our algorithm will be when the array contains only one element that is there is only one student in class. in that case the answer will be only that student.
So out base case for our function name findSequence(a,l) will be
if(l==n-1)
return a[l];
3. Now we have to break our problem in small problem s of one size and then combine results form the sub problems to get the solution of higher problem for example.
if there are two classes with one people each 3 and 4 the answer will be 3 and 4 but if we have a class with these two students 3 and 4 and 3 wins over 4 then we can check after find the lower level that if win(4,3) = 1 then subsequence will be 4,3 else 3,4
in the same way if there is a class with these two people 3 and 4 and the sequence return is 4,3 from this and there is an individual class with 2 which the answer tot his individual class will be 2 but if these three are in same class answer will be 2,4,3 if win(2,4) = 1 else this sequence wont exist.
4. now the problem is how to break the array in to smaller problems . this i will show with the help of a tree
[1,2,3,4]
/ | | \
/ / \ \
[234] [134] [214] [231]
/ | \
[34] [24] [32]
/ \ / \ / \
[3] [4] [2][ 4][3][2]
the problem can be broken in the above way now the original programme
findSequence(a,l)
{
if(l==a.length-1)
return ;
else
{
for(int i=l;i<n;i++)
{
swap(a[l],a[i])
findSequence(a,l+1);
if(wins(a[l],a[l+1])==1)
return;
}
}
}
main()
{
int[] a = new int[n];
for(int i=0;i<n;i++)
a[i]=i
findSequence(a,0)
for(int i=0;i<n;i++)
System.out.print(a[i]+" ");
}
I would also like to give an example
1 2 3 4
x=1 [0 1 0 0
2 0 0 1 1
3 1 0 0 0
4 1 0 1 0
]
for the Above win loose matrix a sample run of the above algo will be.
1. findSequence(a,0)
[1,2,3,4]
2. findSequence(a,1)
[2,3,4]
3. findSequence(a,2)
[3,4]
4, findSequence(a,3)
as l==3
return
now check if wins(3,4) == 1 its false so the loop will continue
5 swap(a[l],a[i])=swap(a[2],a[3] ) = a=[1,2,4,3]
forSequence(a,3)
4 return as l==3
6
if wins(4,3)==1 yes return
7. if wins(2,4) == 1 return;
8 if wins(1,2) == 1 return
answer is
[1,2,4,3]
frenz please check and reply
I think its O(n) solution, the question do not demand all possible solutions, it wants any one.
Algo:
Linklist l = new Linklist()
for each element in N people:
insert(element,l)
insert(element, l)
-- if l is empty:
l.root = element
return
root = l.root
while(root is not null):
if element has won against root:
insert element before root:
break;return
root = root.next
root.next = element
For each person, store lists of everyone they beat.
Backtrack:
- Fill first position with people who have had wins (iterate over all these of course)
- Then: At every position thereafter: Fill every person who has lost to the person in the previous position of the filled array but is not in result array.
Typed this directly in here, so could be buggy
// PRUNE this as you desire.
- S O U N D W A V E October 09, 2013