# The knows API is already defined for you.
# def knows(a: int, b: int) -> bool:
class Solution:
def findCelebrity(self, n: int) -> int:
# Step 1: Find the candidate
candidate = 0
for i in range(1, n):
if knows(candidate, i):
candidate = i
# Step 2: Validate the candidate
for i in range(n):
if i != candidate:
if knows(candidate, i) or not knows(i, candidate):
return -1
return candidate
// The knows API is defined for you.
// bool knows(int a, int b);
class Solution {
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 (i != candidate) {
if (knows(candidate, i) || !knows(i, candidate))
return -1;
}
}
return candidate;
}
};
/* 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) {
int candidate = 0;
for (int i = 1; i < n; i++) {
if (knows(candidate, i)) {
candidate = i;
}
}
for (int i = 0; i < n; i++) {
if (i != candidate) {
if (knows(candidate, i) || !knows(i, candidate)) {
return -1;
}
}
}
return candidate;
}
}
/**
* // The knows API is defined for you.
* var knows = function(personA, personB) {
* ...
* };
*/
/**
* @param {number} n
* @return {number}
*/
var findCelebrity = function(n) {
let candidate = 0;
for (let i = 1; i < n; i++) {
if (knows(candidate, i)) {
candidate = i;
}
}
for (let i = 0; i < n; i++) {
if (i !== candidate) {
if (knows(candidate, i) || !knows(i, candidate)) {
return -1;
}
}
}
return candidate;
};
You are at a party with n
people labeled from 0
to n - 1
. Some people know each other, and some do not. A celebrity is defined as someone who:
knows(a, b)
that returns True
if person a
knows person b
, and False
otherwise.
-1
.
knows
.
At first glance, it might seem that we need to check every pair of people to see who knows whom, which would take a lot of time. For each person, we could check if everyone knows them and if they know no one else. But this would require O(n^2)
calls to knows
, which is inefficient.
Instead, we can realize that if person A
knows person B
, then A
cannot be the celebrity (since celebrities know no one). Likewise, if A
does not know B
, then B
cannot be the celebrity (since everyone must know the celebrity).
This insight allows us to efficiently eliminate non-celebrities and narrow down to a single potential candidate, then verify that candidate.
0
) as the celebrity candidate.i
from 1
to n-1
:i
, then the candidate cannot be the celebrity (since celebrities know no one). So, set i
as the new candidate.i
, keep the current candidate.j
(where j != candidate
):j
(knows(candidate, j) == False
).j
knows the candidate (knows(j, candidate) == True
).-1
(no celebrity).
This approach reduces the number of knows
calls to O(n)
, which is much more efficient than the brute-force method.
Suppose n = 4
and the following "knows" relationships exist:
O(n^2)
calls to knows
(since you check every pair).O(n)
calls (one for each person).O(n)
calls (one for each person, except the candidate).O(n)
calls to knows
.O(1)
extra space (only a few variables are used).
The "Find the Celebrity" problem uses a clever elimination process to efficiently identify the celebrity (if one exists) with only O(n)
calls to the knows
API. By iteratively narrowing down the candidate and then verifying just one person, we avoid the need to check every possible pair. This approach is both simple and elegant, making the most out of the problem's constraints and requirements.