Understand what the interviewer is asking for by using test cases and questions about the problem.
- Established a set (2-3) of test cases to verify their own solution later.
- Established a set (1-2) of edge cases to verify their solution handles complexities.
- Have fully understood the problem and have no clarifying questions.
- Have you verified any Time/Space Constraints for this problem?
Run through a set of example cases:
HAPPY CASE
Input: graph = [[1,1,0],[0,1,0],[1,1,1]]
Output: 1
Input: graph = [[1,0,1],[1,1,0],[0,1,1]]
Output: -1
EDGE CASE
Input: 0 (No people at the party)
Output: -1
Match what this problem looks like to known categories of problems, e.g. Linked List or Dynamic Programming, and strategies or patterns in those categories.
Plan the solution with appropriate visualizations and pseudocode.
General Idea: Use a stack to iterate through all the individuals at the party. Pop the stack and call knows(a, b) on individuals till a celebrity is found.
1) Create a stack and push elements 0 --> N-1 onto the stack
2) Create two variables left and right
3) Pop the first two elements into left and right respectively
4) While the stack has individuals on it:
a) If left knows right, left cannot be a celebrity
i) Pop the next element into left
ii) Refer to right as a potential celebrity
b) If left does not know right, right cannot be a celebrity
i) Pop the next element into right
ii) Refer to left as a potential celebrity
5) The potential celebrity reference is the most valid individual
4) Loop through all individuals and verify:
a) Potential celebrity does not know anyone
b) Everyone except the potential celebrity knows the potential celebrity
5) If valid, return celebrity, else return -1
⚠️ Common Mistakes
Implement the code to solve the algorithm.
def findCelebrity(n: int) -> int:
# base case
if n < 2:
return -1
stack = []
# put all people to the stack
for i in range(n):
stack.append(i)
left = stack.pop()
right = stack.pop()
potential_celebrity = left if not knows(left, right) else right
while len(stack) > 0:
if knows(left, right):
potential_celebrity = right
left = stack.pop()
else:
potential_celebrity = left
right = stack.pop()
# double check the potential celebrity
for i in range(n):
if i != potential_celebrity and (not knows(i, potential_celebrity) or knows(potential_celebrity, i)):
return -1
return potential_celebrity
public class Solution extends Relation {
public int findCelebrity(int n) {
// base case
if (n <= 0) return -1;
if (n == 1) return 0;
Stack<Integer> stack = new Stack<>();
// put all people to the stack
for (int i = 0; i < n; i++) stack.push(i);
int a = 0, b = 0;
while (stack.size() > 1) {
a = stack.pop(); b = stack.pop();
if (knows(a, b))
// a knows b, so a is not the celebrity, but b may be
stack.push(b);
else
// a doesn't know b, so b is not the celebrity, but a may be
stack.push(a);
}
// double check the potential celebrity
int c = stack.pop();
for (int i = 0; i < n; i++)
// c should not know anyone else
if (i != c && (knows(c, i) || !knows(i, c)))
return -1;
return c;
}
}
Review the code by running specific example(s) and recording values (watchlist) of your code's variables along the way.
Evaluate the performance of your algorithm and state any strong/weak or future potential work.
Time Complexity: O(n), where n is the number of API calls. For each of the n people, we need to check whether or not they are a celebrity. Checking whether or not somebody is a celebrity requires making 2 API calls for each of the n - 1 other people.
Space Complexity: O(n), for the stack used.