1
2
3
4
5
6
7
8
/* The knows API is defined in the parent class Relation.
boolean knows(int a, int b); */

public class Solution extends Relation {
public int findCelebrity(int n) {

}
}

  1. Best. Two pass.
  • 1st for: decides candidate; note candidate to be k; so 0 to k-1 don’t know k, k+1 to n-1 also don’t know k because candidate = k.
  • 2nd: this candidate doesn’t know others, check if all others know this person.
1
2
3
4
5
6
7
8
9
10
public int findCelebrity(int n) {
int candidate = 0;
for (int i = 1; i < n; ++i) {
if (knows(candidate, i)) candidate = i;
}
for (int i = 0; i < n; ++i) {
if (candidate != i && (knows(candidate, i) || !knows(i, candidate))) return -1;
}
return candidate;
}
  1. Stack. Two pass.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/* The knows API is defined in the parent class Relation.
boolean knows(int a, int b); */

public class Solution extends Relation {
public int findCelebrity(int n) {
if (n <= 0) return -1;
if (n == 1) return 0;

Stack<Integer> st = new Stack<>();
for (int i = 0; i < n; ++i) {
st.push(i);
}

int a = 0, b = 0;
while (st.size() > 1) {
a = st.pop(); b = st.pop();
if (knows(a, b)) st.push(b); else st.push(a);
}

int c = st.pop();
for (int i = 0; i < n; ++i) {
if (c != i && (knows(c, i) || !knows(i, c))) return -1;
}
return c;
}
}

Why stack not list? list: add, remove could take O(n), stack pop is O(1)