A celebrity is a person who is known by everyone else at the party but does not know anyone in return. Given a square matrix M of size N x N where M[i][j] is 1 if person i knows person j, and 0 otherwise, determine if there is a celebrity at the party. Return the index of the celebrity or -1 if no such person exists.
Note that M[i][i] is always 0.
Input: M = [ [0, 1, 1, 0], [0, 0, 0, 0], [1, 1, 0, 0], [0, 1, 1, 0] ]
Output: 1
Explanation: Person 1 does not know anyone and is known by persons 0, 2, and 3. Therefore, person 1 is the celebrity.
Input: M = [ [0, 1], [1, 0] ]
Output: -1
Explanation: Both persons know each other, so there is no celebrity.
Input: M = [ [0, 1, 0], [0, 0, 0], [0, 1, 0] ]
A naive approach to solve this problem is to count all the persons that are known for each person and to count all the person that each person knows. This way the celebrity can be identified by finding the person who is known by all other people and who does not know any person.
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
// Function to find the index of celebrity
int celebrity(vector<vector<int>> &M){
// Size of given matrix
int n = M.size();
/* To store count of people who
know person of index i */
vector<int> knowMe(n, 0);
/* To store count of people who
the person of index i knows */
vector<int> Iknow(n, 0);
// Traverse on given matrix
for(int i=0; i < n; i++) {
for(int j=0; j < n; j++) {
// If person i knows person j
if(M[i][j] == 1) {
knowMe[j]++;
Iknow[i]++;
}
}
}
// Traverse for all persons to find the celebrity
for(int i=0; i < n; i++) {
// Return the index of celebrity
if(knowMe[i] == n-1 && Iknow[i] == 0) {
return i;
}
}
// Return -1 if no celebrity is found
return -1;
}
};
int main() {
vector<vector<int>> M = {
{0, 1, 1, 0},
{0, 0, 0, 0},
{1, 1, 0, 0},
{0, 1, 1, 0}
};
/* Creating an instance of
Solution class */
Solution sol;
// Function call to find the index of celebrity
int ans = sol.celebrity(M);
cout << "The index of celebrity is: " << ans;
return 0;
}
import java.util.*;
class Solution {
// Function to find the index of celebrity
public int celebrity(int[][] M) {
// Size of given matrix
int n = M.length;
/* To store count of people who
know person of index i */
int[] knowMe = new int[n];
/* To store count of people who
the person of index i knows */
int[] Iknow = new int[n];
// Traverse on given matrix
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
// If person i knows person j
if (M[i][j] == 1) {
knowMe[j]++;
Iknow[i]++;
}
}
}
// Traverse for all persons to find the celebrity
for (int i = 0; i < n; i++) {
// Return the index of celebrity
if (knowMe[i] == n - 1 && Iknow[i] == 0) {
return i;
}
}
// Return -1 if no celebrity is found
return -1;
}
public static void main(String[] args) {
int[][] M = {
{0, 1, 1, 0},
{0, 0, 0, 0},
{1, 1, 0, 0},
{0, 1, 1, 0}
};
/* Creating an instance of
Solution class */
Solution sol = new Solution();
// Function call to find the index of celebrity
int ans = sol.celebrity(M);
System.out.println("The index of celebrity is: " + ans);
}
}
class Solution:
# Function to find the index of celebrity
def celebrity(self, M):
# Size of given matrix
n = len(M)
# To store count of people who
# know person of index i
knowMe = [0] * n
# To store count of people who
# the person of index i knows
Iknow = [0] * n
# Traverse on given matrix
for i in range(n):
for j in range(n):
# If person i knows person j
if M[i][j] == 1:
knowMe[j] += 1
Iknow[i] += 1
# Traverse for all persons to find the celebrity
for i in range(n):
# Return the index of celebrity
if knowMe[i] == n - 1 and Iknow[i] == 0:
return i
# Return -1 if no celebrity is found
return -1
if __name__ == "__main__":
M = [
[0, 1, 1, 0],
[0, 0, 0, 0],
[1, 1, 0, 0],
[0, 1, 1, 0]
]
# Creating an instance of
# Solution class
sol = Solution()
# Function call to find the index of celebrity
ans = sol.celebrity(M)
print("The index of celebrity is:", ans)
class Solution {
// Function to find the index of celebrity
celebrity(M) {
// Size of given matrix
const n = M.length;
/* To store count of people who
know person of index i */
let knowMe = new Array(n).fill(0);
/* To store count of people who
the person of index i knows */
let Iknow = new Array(n).fill(0);
// Traverse on given matrix
for (let i = 0; i < n; i++) {
for (let j = 0; j < n; j++) {
// If person i knows person j
if (M[i][j] == 1) {
knowMe[j]++;
Iknow[i]++;
}
}
}
// Traverse for all persons to find the celebrity
for (let i = 0; i < n; i++) {
// Return the index of celebrity
if (knowMe[i] == n - 1 && Iknow[i] == 0) {
return i;
}
}
// Return -1 if no celebrity is found
return -1;
}
}
const M = [
[0, 1, 1, 0],
[0, 0, 0, 0],
[1, 1, 0, 0],
[0, 1, 1, 0]
];
/* Creating an instance of
Solution class */
const sol = new Solution();
// Function call to find the index of celebrity
const ans = sol.celebrity(M);
console.log("The index of celebrity is:", ans);
Time Complexity: O(N2) (where N is the size of square matrix)
Space Complexity: O(N)
The two lists to store the count of how many people each person knows and how many people know each person takes O(N) space each.
Since there can be only one celebrity, instead of finding the celebrity, the people that are not celebrity can be determined. If all such people are found, any person left (if it exists) will be the celebrity.
THe two conditions to identify the celebrity is:
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
// Function to find the index of celebrity
int celebrity(vector<vector<int>> &M){
// Size of given matrix
int n = M.size();
// Top and Down pointers
int top = 0, down = n-1;
// Traverse for all the people
while(top < down) {
/* If top knows down,
it can not be a celebrity */
if(M[top][down] == 1) {
top = top + 1;
}
/* If down knowns top,
it can not be a celebrity */
else if(M[down][top] == 1) {
down = down - 1;
}
/* If both does not know each other,
both cannot be the celebrity */
else {
top++;
down--;
}
}
// Return -1 if no celebrity is found
if(top > down) return -1;
/* Check if the person pointed
by top is celebrity */
for(int i=0; i < n; i++) {
if(i == top) continue;
// Check if it is not a celebrity
if(M[top][i] == 1 || M[i][top] == 0) {
return -1;
}
}
// Return the index of celebrity
return top;
}
};
int main() {
vector<vector<int>> M = {
{0, 1, 1, 0},
{0, 0, 0, 0},
{1, 1, 0, 0},
{0, 1, 1, 0}
};
/* Creating an instance of
Solution class */
Solution sol;
// Function call to find the index of celebrity
int ans = sol.celebrity(M);
cout << "The index of celebrity is: " << ans;
return 0;
}
import java.util.*;
class Solution {
// Function to find the index of celebrity
public int celebrity(int[][] M) {
// Size of given matrix
int n = M.length;
// Top and Down pointers
int top = 0, down = n - 1;
// Traverse for all the people
while (top < down) {
/* If top knows down,
it can not be a celebrity */
if (M[top][down] == 1) {
top = top + 1;
}
/* If down knows top,
it can not be a celebrity */
else if (M[down][top] == 1) {
down = down - 1;
}
/* If both do not know each other,
both cannot be the celebrity */
else {
top++;
down--;
}
}
// Return -1 if no celebrity is found
if (top > down) return -1;
/* Check if the person pointed
by top is celebrity */
for (int i = 0; i < n; i++) {
if (i == top) continue;
// Check if it is not a celebrity
if (M[top][i] == 1 || M[i][top] == 0) {
return -1;
}
}
// Return the index of celebrity
return top;
}
public static void main(String[] args) {
int[][] M = {
{0, 1, 1, 0},
{0, 0, 0, 0},
{1, 1, 0, 0},
{0, 1, 1, 0}
};
/* Creating an instance of
Solution class */
Solution sol = new Solution();
// Function call to find the index of celebrity
int ans = sol.celebrity(M);
System.out.println("The index of celebrity is: " + ans);
}
}
class Solution:
# Function to find the index of celebrity
def celebrity(self, M):
# Size of given matrix
n = len(M)
# Top and Down pointers
top, down = 0, n - 1
# Traverse for all the people
while top < down:
# If top knows down,
# it can not be a celebrity
if M[top][down] == 1:
top += 1
# If down knows top,
# it can not be a celebrity
elif M[down][top] == 1:
down -= 1
# If both do not know each other,
# both cannot be the celebrity
else:
top += 1
down -= 1
# Return -1 if no celebrity is found
if top > down:
return -1
# Check if the person pointed
# by top is celebrity
for i in range(n):
if i == top:
continue
# Check if it is not a celebrity
if M[top][i] == 1 or M[i][top] == 0:
return -1
# Return the index of celebrity
return top
if __name__ == "__main__":
M = [
[0, 1, 1, 0],
[0, 0, 0, 0],
[1, 1, 0, 0],
[0, 1, 1, 0]
]
# Creating an instance of
# Solution class
sol = Solution()
# Function call to find the index of celebrity
ans = sol.celebrity(M)
print("The index of celebrity is:", ans)
class Solution {
// Function to find the index of celebrity
celebrity(M) {
// Size of given matrix
const n = M.length;
// Top and Down pointers
let top = 0, down = n - 1;
// Traverse for all the people
while (top < down) {
/* If top knows down,
it can not be a celebrity */
if (M[top][down] == 1) {
top = top + 1;
}
/* If down knows top,
it can not be a celebrity */
else if (M[down][top] == 1) {
down = down - 1;
}
/* If both do not know each other,
both cannot be the celebrity */
else {
top++;
down--;
}
}
// Return -1 if no celebrity is found
if (top > down) return -1;
/* Check if the person pointed
by top is celebrity */
for (let i = 0; i < n; i++) {
if (i === top) continue;
// Check if it is not a celebrity
if (M[top][i] == 1 || M[i][top] == 0) {
return -1;
}
}
// Return the index of celebrity
return top;
}
}
const M = [
[0, 1, 1, 0],
[0, 0, 0, 0],
[1, 1, 0, 0],
[0, 1, 1, 0]
];
/* Creating an instance of
Solution class */
const sol = new Solution();
// Function call to find the index of celebrity
const ans = sol.celebrity(M);
console.log("The index of celebrity is:", ans);
Time Complexity: O(N) (where N is the size of given square matrix)
Space Complexity: O(1)
Using only a couple of variables.
Q: Why do we check both rows and columns separately in validation?
A: Row Check: Ensures the candidate does not know anyone. Column Check: Ensures everyone knows the candidate. Both conditions must be met for a valid celebrity.
Q: Can this problem be solved using a graph representation?
A: Yes! Represent it as a directed graph, where an edge i → j means i knows j. A celebrity is a node with N-1 incoming edges and 0 outgoing edges.
Q: What if we want to find the top K most famous people instead of just one celebrity?
A: Modify the approach to rank individuals based on the count of 1s in their column.