The Celebrity Problem

In a party of N people, only one person is known to everyone. Such a person may be present in the party, if yes, (s)he doesn’t know anyone in the party. We can only ask questions like “does A know B? “. Find the stranger (celebrity) in the minimum number of questions.
We can describe the problem input as an array of numbers/characters representing persons in the party. We also have a hypothetical function HaveAcquaintance(A, B) which returns true if A knows B, false otherwise. How can we solve the problem. 

Examples:  

Input:
MATRIX = { {0, 0, 1, 0},
           {0, 0, 1, 0},
           {0, 0, 0, 0},
           {0, 0, 1, 0} }
Output:id = 2
Explanation: The person with ID 2 does not 
know anyone but everyone knows him

Input:
MATRIX = { {0, 0, 1, 0},
           {0, 0, 1, 0},
           {0, 1, 0, 0},
           {0, 0, 1, 0} }
Output: No celebrity
Explanation: There is no celebrity.

We measure the complexity in terms of calls made to HaveAcquaintance().

Method 1: This uses Graph to arrive at the particular solution.

  • Approach: 
    Model the solution using graphs. Initialize indegree and outdegree of every vertex as 0. If A knows B, draw a directed edge from A to B, increase indegree of B and outdegree of A by 1. Construct all possible edges of the graph for every possible pair [i, j]. There are NC2 pairs. If a celebrity is present in the party, there will be one sink node in the graph with outdegree of zero and indegree of N-1. 
     
  • Algorithm: 
    1. Create two arrays indegree and outdegree, to store the indegree and outdegree
    2. Run a nested loop, the outer loop from 0 to n and inner loop from 0 to n.
    3. For every pair i, j check if i knows j then increase the outdegree of i and indegree of j
    4. For every pair i, j check if j knows i then increase the outdegree of j and indegree of i
    5. Run a loop from 0 to n and find the id where the indegree is n-1 and outdegree is 0
  • Implementation:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to find celebrity
#include <bits/stdc++.h>
#include <list>
using namespace std;
   
// Max # of persons in the party
#define N 8
   
// Person with 2 is celebrity
bool MATRIX[N][N] = {{0, 0, 1, 0},
                    {0, 0, 1, 0},
                    {0, 0, 0, 0},
                    {0, 0, 1, 0}};
   
bool knows(int a, int b)
{
    return MATRIX[a][b];
}
   
// Returns -1 if celebrity
// is not present. If present,
// returns id (value from 0 to n-1).
int findCelebrity(int n)
{
    //the graph needs not be constructed
    //as the edges can be found by
    //using knows function
      
    //degree array;
    int indegree[n]={0},outdegree[n]={0};
      
    //query for all edges
    for(int i=0; i<n; i++)
    {
        for(int j=0; j<n; j++)
        {
            int x = knows(i,j);
              
            //set the degrees
            outdegree[i]+=x;
            indegree[j]+=x;
        }
    }
      
    //find a person with indegree n-1
    //and out degree 0
    for(int i=0; i<n; i++)
    if(indegree[i] == n-1 && outdegree[i] == 0)
        return i;
      
    return -1;
}
   
// Driver code
int main()
{
    int n = 4;
    int id = findCelebrity(n);
    id == -1 ? cout << "No celebrity" :
               cout << "Celebrity ID " << id;
    return 0;
}

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program to find celebrity 
  
# Max # of persons in the party 
N = 8
  
# Person with 2 is celebrity 
MATRIX = [ [ 0, 0, 1, 0 ], 
           [ 0, 0, 1, 0 ], 
           [ 0, 0, 0, 0 ], 
           [ 0, 0, 1, 0 ] ]
             
def knows(a, b): 
      
  return MATRIX[a][b] 
  
def findCelebrity(n): 
      
    # The graph needs not be constructed 
    # as the edges can be found by 
    # using knows function 
        
    # degree array; 
    indegree = [0 for x in range(n)]
    outdegree = [0 for x in range(n)]
        
    # Query for all edges 
    for i in range(n): 
        for j in range(n): 
            x = knows(i, j)
                
            # Set the degrees 
            outdegree[i] +=
            indegree[j] +=
        
    # Find a person with indegree n-1 
    # and out degree 0 
    for i in range(n):
        if (indegree[i] == n - 1 and 
           outdegree[i] == 0):
            return
              
    return -1
      
# Driver code    
if __name__ == '__main__':
      
    n = 4 
    id_ = findCelebrity(n)
      
    if id_ == -1:
        print("No celebrity")
    else:
        print("Celebrity ID", id_)
  
# This code is contributed by UnworthyProgrammer

chevron_right


Output : 

Celebrity ID 2
  • Complexity Analysis: 
    • Time Complexity: O(n2). 
      A nested loop is run traversing the array, SO the time complexity is O(n2)
    • Space Complexity: O(n). 
      Since extra space of size n is required.
  • Approach : 
    The problem can be decomposed into a combination of smaller instances. Say, if the celebrity of N-1 persons is known, can the solution to N? There are two possibilities, Celebrity(N-1) may know N, or N already knew Celebrity(N-1). In the former case, N will be a celebrity if N. In the latter case, check that Celebrity(N-1) doesn’t know N. 
    The above-mentioned approach use Recursion to find the celebrity among n persons. It is necessary to find a celebrity among n-1 persons. So while calculating the celebrity of i persons the function calls itself to find the celebrity of i-1 persons and continues doing so until the base case is found.
  • Algorithm : 
    1. Create a recursive function that takes an integer n.
    2. Check the base case, if the value of n is 0 then return 0.
    3. Call the recursive function and get the ID of celebrity from the first n-1 elements.
    4. If the id is -1 then assign n as celebrity and return the value.
    5. If the celebrity of first n-1 elements knows n-1 and n-1 does not know the celebrity then return n-1, (0 based indexing)
    6. If the celebrity of first n-1 elements does not know n-1 and n-1 knows the celebrity then return id of celebrity of n-1 elements, (0 based indexing)
    7. Else return -1
    8. Create a wrapper function and check whether the id returned by the function is really the celebrity or not.
  • Implementation: 

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to find celebrity
#include <bits/stdc++.h>
#include <list>
using namespace std;
  
// Max # of persons in the party
#define N 8
  
// Person with 2 is celebrity
bool MATRIX[N][N] = {{0, 0, 1, 0},
                    {0, 0, 1, 0},
                    {0, 1, 0, 0},
                    {0, 0, 1, 0}};
  
bool knows(int a, int b)
{
    return MATRIX[a][b];
}
  
// Returns -1 if celebrity
// is not present. If present,
// returns id (value from 0 to n-1).
int findCelebrity(int n)
{
    //base case
    if(n == 1)
    return n - 1;
      
    //find the celebrity with n-1
    //persons
    int id = findCelebrity(n-1);
      
    //if there are no celebrities
    if(id == -1)
        return n-1;
      
    // if the celebrity knows the
    //nth person
    else if(knows(id, n-1) && !knows(n-1, id))
    {
        return n-1; 
    }
    //if the nth person knows the
    //celebrity then return the id
    else if(knows(n-1, id) && !knows(id, n-1))
    {
        return id;
    }
  
    //if there is no celebrity 
    return -1;
}
  
// Returns -1 if celebrity
// is not present. If present,
// returns id (value from 0 to n-1).
// a wrapper over findCelebrity
int Celebrity(int n)
{
    //find the celebrity
    int id = findCelebrity(n);
      
    //check if the celebrity found
    //is really the celebrity
    if(id == -1)
        return id;
    else
    {
        int c1=0, c2=0;
  
        //check the id is really the
        //celebrity
        for(int i=0; i<n; i++)
        if(i != id)
        {
            c1+=knows(id, i);
            c2+=knows(i, id);
        }
          
        //if the person is known to
        //everyone.
        if(c1==0 && c2==n-1)
            return id;
          
        return -1;
    }
}
  
// Driver code
int main()
{
    int n = 4;
    int id = Celebrity(n);
    id == -1 ? cout << "No celebrity" :
            cout << "Celebrity ID " << id;
    return 0;
}

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program to find celebrity 
  
# Max # of persons in the party 
N = 8 
  
# Person with 2 is celebrity 
MATRIX = [ [ 0, 0, 1, 0 ], 
           [ 0, 0, 1, 0 ], 
           [ 0, 1, 0, 0 ], 
           [ 0, 0, 1, 0 ] ] 
  
def knows(a, b): 
      
    return MATRIX[a][b] 
  
# Returns -1 if celebrity 
# is not present. If present, 
# returns id (value from 0 to n-1). 
def findCelebrity(n):
      
    # Base case 
    if (n == 1): 
        return n - 1 
      
    # Find the celebrity with n-1 
    # persons 
    id_ = findCelebrity(n - 1)
      
    # If there are no celebrities 
    if (id_ == -1): 
        return n - 1 
      
    # If the celebrity knows the 
    # nth person 
    elif (knows(id_, n - 1) and 
      not(knows(n - 1, id_))): 
        return n - 1
          
    # If the nth person knows the 
    # celebrity then return the id 
    elif (knows(n - 1, id_) and 
      not(knows(id_, n - 1))): 
        return id_ 
  
    # If there is no celebrity 
    return - 1 
  
# Returns -1 if celebrity 
# is not present. If present, 
# returns id (value from 0 to n-1). 
# a wrapper over findCelebrity 
def Celebrity(n): 
      
    # Find the celebrity 
    id_ = findCelebrity(n) 
      
    # Check if the celebrity found 
    # is really the celebrity 
    if (id_ == -1): 
        return id_
    else:
        c1 = 0
        c2 = 0 
  
        # Check the id is really the 
        # celebrity 
        for i in range(n): 
            if (i != id_): 
                c1 += knows(id_, i) 
                c2 += knows(i, id_)
          
        # If the person is known to 
        # everyone. 
        if (c1 == 0 and c2 == n - 1): 
            return id_ 
          
        return -1
   
# Driver code 
if __name__ == '__main__':
      
    n = 4
    id_ = Celebrity(n) 
      
    if id_ == -1:
        print("No celebrity")
    else:
        print("Celebrity ID", id_)
  
# This code is contributed by UnworthyProgrammer

chevron_right


Output :



No celebrity
  • Complexity Analysis: 
    • Time Complexity: O(n). 
      The recursive function is called n times, so the time complexity is O(n).
    • Space Complexity: O(1). 
      As no extra space is required.
  • Approach: There are some observations based on elimination technique (Refer Polya’s How to Solve It book). 
    • If A knows B, then A can’t be a celebrity. Discard A, and B may be celebrity.
    • If A doesn’t know B, then B can’t be a celebrity. Discard B, and A may be celebrity.
    • Repeat above two steps till there is only one person.
    • Ensure the remained person is a celebrity. (What is the need of this step?)
  • Algorithm: 
    1. Create a stack and push all the id’s in the stack.
    2. Run a loop while there are more than 1 element in the stack.
    3. Pop top two element from the stack (represent them as A and B)
    4. Check if A knows B, then A can’t be a celebrity and push B in stack. Check if A doesn’t know B, then B can’t be a celebrity push A in stack
    5. Assign the remaining element in the stack as the celebrity
    6. Run a loop from 0 to n-1 and find the count of persons who knows the celebrity and the number of people whom the celebrity knows. if the count of persons who knows the celebrity is n-1 and the count of people whom the celebrity knows is 0 then return the id of celebrity else return -1.
  • Implementation: 
     

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to find celebrity
#include <bits/stdc++.h>
#include <list>
using namespace std;
  
// Max # of persons in the party
#define N 8
  
// Person with 2 is celebrity
bool MATRIX[N][N] = {{0, 0, 1, 0},
                    {0, 0, 1, 0},
                    {0, 0, 0, 0},
                    {0, 0, 1, 0}};
  
bool knows(int a, int b)
{
    return MATRIX[a][b];
}
  
// Returns -1 if celebrity
// is not present. If present,
// returns id (value from 0 to n-1).
int findCelebrity(int n)
{
    // Handle trivial 
    // case of size = 2
    stack<int> s;
  
    // Celebrity
    int C; 
  
    // Push everybody to stack
    for (int i = 0; i < n; i++)
        s.push(i);
  
    // Extract top 2
    int A = s.top();
    s.pop();
    int B = s.top();
    s.pop();
  
    // Find a potential celebrity
    while (s.size() > 1)
    {
        if (knows(A, B))
        {
            A = s.top();
            s.pop();
        }
        else
        {
            B = s.top();
            s.pop();
        }
    }
    // If there are only two people 
    // and there is no
    // potential candicate
    if(s.empty())
        return -1;
    
    
    // Potential candidate?
    C = s.top();
    s.pop();
  
    // Last candidate was not 
    // examined, it leads one 
    // excess comparison (optimize)
    if (knows(C, B))
        C = B;
  
    if (knows(C, A))
        C = A;
  
    // Check if C is actually
    // a celebrity or not
    for (int i = 0; i < n; i++)
    {
        // If any person doesn't 
        // know 'a' or 'a' doesn't 
        // know any person, return -1
        if ( (i != C) &&
                (knows(C, i) || 
                 !knows(i, C)) )
            return -1;
    }
  
    return C;
}
  
// Driver code
int main()
{
    int n = 4;
    int id = findCelebrity(n);
    id == -1 ? cout << "No celebrity" :
               cout << "Celebrity ID " << id;
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to find celebrity using
// stack data structure
import java.util.Stack;
  
class GFG 
{
    // Person with 2 is celebrity
    static int MATRIX[][] = { { 0, 0, 1, 0 },
                            { 0, 0, 1, 0 },
                            { 0, 0, 0, 0 }, 
                            { 0, 0, 1, 0 } };
  
    // Returns true if a knows 
    // b, false otherwise
    static boolean knows(int a, int b) 
    {
        boolean res = (MATRIX[a][b] == 1) ? 
                                     true
                                     false;
        return res;
    }
  
    // Returns -1 if celebrity 
    // is not present. If present,
    // returns id (value from 0 to n-1).
    static int findCelebrity(int n) 
    {
        Stack<Integer> st = new Stack<>();
        int c;
  
        // Step 1 :Push everybody
        // onto stack
        for (int i = 0; i < n; i++) 
        {
            st.push(i);
        }
  
        while (st.size() > 1
        {
            // Step 2 :Pop off top
            // two persons from the 
            // stack, discard one 
            // person based on return
            // status of knows(A, B).
            int a = st.pop();
            int b = st.pop();
  
            // Step 3 : Push the 
            // remained person onto stack.
            if (knows(a, b)) 
            {
                st.push(b);
            }
  
            else
                st.push(a);
        }
        
        // If there are only two people 
        // and there is no
        // potential candicate
        if(st.empty())
            return -1;
  
        c = st.pop();
  
        // Step 5 : Check if the last 
        // person is celebrity or not
        for (int i = 0; i < n; i++) 
        {
            // If any person doesn't
            //  know 'c' or 'a' doesn't 
            // know any person, return -1
            if (i != c && (knows(c, i) || 
                          !knows(i, c)))
                return -1;
        }
        return c;
    }
  
    // Driver Code
    public static void main(String[] args) 
    {
        int n = 4;
        int result = findCelebrity(n);
        if (result == -1
        {
            System.out.println("No Celebrity");
        
        else
            System.out.println("Celebrity ID "
                                        result);
    }
}
  
// This code is contributed 
// by Rishabh Mahrsee

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program to find celebrity
# using stack data structure 
  
# Max # of persons in the party
N = 8
  
# Person with 2 is celebrity
MATRIX = [ [ 0, 0, 1, 0 ],
           [ 0, 0, 1, 0 ],
           [ 0, 0, 0, 0 ],
           [ 0, 0, 1, 0 ] ]
  
def knows(a, b):
      
    return MATRIX[a][b]
  
# Returns -1 if celebrity
# is not present. If present,
# returns id (value from 0 to n-1).
def findCelebrity(n):
      
    # Handle trivial 
    # case of size = 2
    s = [] 
  
    # Push everybody to stack
    for i in range(n):
        s.append(i)
  
    # Extract top 2
    A = s.pop()
    B = s.pop()
  
    # Find a potential celebrity
    while (len(s) > 1):
        if (knows(A, B)):
            A = s.pop()
        else:
            B = s.pop()
              
    # If there are only two people 
    # and there is no
    # potential candicate
    if(len(s) == 0):
        return -1
          
    # Potential candidate?
    C = s.pop();
  
    # Last candidate was not 
    # examined, it leads one 
    # excess comparison (optimize)
    if (knows(C, B)):
        C = B
          
    if (knows(C, A)):
        C = A
  
    # Check if C is actually
    # a celebrity or not
    for i in range(n):
      
        # If any person doesn't 
        # know 'a' or 'a' doesn't 
        # know any person, return -1
        if ((i != C) and 
           (knows(C, i) or 
           not(knows(i, C)))):
            return -1
  
    return C
      
# Driver code
if __name__ == '__main__':
      
    n = 4
    id_ = findCelebrity(n)
      
    if id_ == -1:
        print("No celebrity"
    else:
      print("Celebrity ID ", id_)
  
# This code is contributed by UnworthyProgrammer

chevron_right


Output : 

Celebrity ID 2
  • Complexity Analysis: 
    • Time Complexity: O(n). 
      Total number of comparisons 3(N-1), so the time complexity is O(n).
    • Space Complexity: O(n). 
      n extra space is needed to store the stack.
  • Approach: The idea is to use two pointers, one from start and one from the end. Assume the start person is A, and the end person is B. If A knows B, then A must not be the celebrity. Else, B must not be the celebrity. At the end of the loop, only one index will be left as a celebrity. Go through each person again and check whether this is the celebrity. 
    The Two Pointer approach can be used where two pointers can be assigned, one at the start and other at the end and the elements can be compared and the search space can be reduced. 
     
  • Algorithm : 
    1. Create two indices a and b, where a = 0 and b = n-1
    2. Run a loop until a is less than b.
    3. Check if a knows b, then a can’t be celebrity. so increment a, i.e. a++
    4. Else b cannot be celebrity, so decrement b, i.e. b–
    5. Assign a as the celebrity
    6. Run a loop from 0 to n-1 and find the count of persons who knows the celebrity and the number of people whom the celebrity knows. if the count of persons who knows the celebrity is n-1 and the count of people whom the celebrity knows is 0 then return the id of celebrity else return -1.
  • Implementation. 
     

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to find 
// celebrity in O(n) time
// and O(1) extra space
#include <bits/stdc++.h>
using namespace std;
  
// Max # of persons in the party
#define N 8
  
// Person with 2 is celebrity
bool MATRIX[N][N] = {{0, 0, 1, 0},
                     {0, 0, 1, 0},
                     {0, 0, 0, 0},
                     {0, 0, 1, 0}
};
  
bool knows(int a, int b)
{
    return MATRIX[a][b];
}
  
// Returns id of celebrity
int findCelebrity(int n)
{
    // Initialize two pointers 
    // as two corners
    int a = 0;
    int b = n - 1;
  
    // Keep moving while 
    // the two pointers
    // don't become same. 
    while (a < b)
    {
        if (knows(a, b))
            a++;
        else
            b--;
    }
  
    // Check if a is actually
    // a celebrity or not
    for (int i = 0; i < n; i++)
    {
        // If any person doesn't 
        // know 'a' or 'a' doesn't
        // know any person, return -1
        if ( (i != a) &&
                (knows(a, i) || 
                !knows(i, a)) )
            return -1;
    }
  
    return a;
}
  
// Driver code
int main()
{
    int n = 4;
    int id = findCelebrity(n);
    id == -1 ? cout << "No celebrity" :
               cout << "Celebrity ID " 
                    << id;
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to find 
// celebrity using two 
// pointers
  
class GFG 
{
    // Person with 2 is celebrity
    static int MATRIX[][] = { { 0, 0, 1, 0 },
                               { 0, 0, 1, 0 }, 
                              { 0, 0, 0, 0 },
                              { 0, 0, 1, 0 } };
  
    // Returns true if a knows
    // b, false otherwise
    static boolean knows(int a, int b) 
    {
        boolean res = (MATRIX[a][b] == 1) ? 
                                     true
                                     false;
        return res;
    }
  
    // Returns -1 if celebrity 
    // is not present. If present, 
    // returns id (value from 0 to n-1).
    static int findCelebrity(int n) 
    {
        // Initialize two pointers 
        // as two corners
        int a = 0;
        int b = n - 1;
          
        // Keep moving while 
        // the two pointers
        // don't become same.
        while (a < b) 
        {
            if (knows(a, b))
                a++;
            else
                b--;
        }
  
        // Check if a is actually 
        // a celebrity or not
        for (int i = 0; i < n; i++) 
        {
            // If any person doesn't 
            // know 'a' or 'a' doesn't
            // know any person, return -1
            if (i != a && (knows(a, i) || 
                           !knows(i, a)))
                return -1;
        }
        return a;
    }
  
    // Driver Code
    public static void main(String[] args) 
    {
        int n = 4;
        int result = findCelebrity(n);
        if (result == -1
        {
            System.out.println("No Celebrity");
        
        else
            System.out.println("Celebrity ID "
                                        result);
    }
}
  
// This code is contributed by Rishabh Mahrsee

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program to find  
# celebrity in O(n) time 
# and O(1) extra space 
  
# Max # of persons in the party
N = 8
  
# Person with 2 is celebrity
MATRIX = [ [ 0, 0, 1, 0 ],
           [ 0, 0, 1, 0 ],
           [ 0, 0, 0, 0 ],
           [ 0, 0, 1, 0 ] ]
  
def knows(a, b):
      
  return MATRIX[a][b]
  
# Returns id of celebrity
def findCelebrity(n):
      
    # Initialize two pointers 
    # as two corners
    a = 0
    b = n - 1
  
    # Keep moving while 
    # the two pointers
    # don't become same. 
    while (a < b):
        if (knows(a, b)):
            a += 1
        else:
            b -= 1
  
    # Check if a is actually
    # a celebrity or not
    for i in range(n):
          
        # If any person doesn't 
        # know 'a' or 'a' doesn't
        # know any person, return -1
        if ((i != a) and 
            (knows(a, i) or 
            not(knows(i, a)))):
            return -1
          
    return a
  
# Driver code
if __name__ == '__main__':
      
    n = 4
    id_ = findCelebrity(n)
      
    if (id_ == -1):  
      print("No celebrity"
    else:
      print("Celebrity ID ", id_)
        
# This code is contributed by UnworthyProgrammer

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to find 
// celebrity using two 
// pointers
using System;
  
class GFG 
{
    // Person with 2 is celebrity
    static int [,]MATRIX = {{ 0, 0, 1, 0 },
                            { 0, 0, 1, 0 }, 
                            { 0, 0, 0, 0 },
                            { 0, 0, 1, 0 }};
  
    // Returns true if a knows
    // b, false otherwise
    static bool knows(int a, int b) 
    {
        bool res = (MATRIX[a, b] == 1) ? 
                                  true
                                  false;
        return res;
    }
  
    // Returns -1 if celebrity 
    // is not present. If present, 
    // returns id (value from 0 to n-1).
    static int findCelebrity(int n) 
    {
        // Initialize two pointers 
        // as two corners
        int a = 0;
        int b = n - 1;
          
        // Keep moving while 
        // the two pointers
        // don't become same.
        while (a < b) 
        {
            if (knows(a, b))
                a++;
            else
                b--;
        }
  
        // Check if a is actually 
        // a celebrity or not
        for (int i = 0; i < n; i++) 
        {
            // If any person doesn't 
            // know 'a' or 'a' doesn't
            // know any person, return -1
            if (i != a && (knows(a, i) || 
                          !knows(i, a)))
                return -1;
        }
        return a;
    }
  
    // Driver Code
    public static void Main() 
    {
        int n = 4;
        int result = findCelebrity(n);
        if (result == -1) 
        {
            Console.WriteLine("No Celebrity");
        
        else
            Console.WriteLine("Celebrity ID "
                                       result);
    }
}
  
// This code is contributed by anuj_67.

chevron_right


PHP

filter_none

edit
close

play_arrow

link
brightness_4
code

<?php
// PHP program to find 
// celebrity in O(n) time
// and O(1) extra space
  
  
// Max # of persons 
// in the party $N = 8;
  
// Person with 2 is celebrity
$MATRIX = array(array(0, 0, 1, 0),
                array(0, 0, 1, 0),
                array(0, 0, 0, 0),
                array(0, 0, 1, 0));
  
function knows( $a, $b)
{
    global $MATRIX;
    return $MATRIX[$a][$b];
}
  
// Returns id of celebrity
function findCelebrity( $n)
{
    // Initialize two 
    // pointers as two corners
    $a = 0;
    $b = $n - 1;
  
    // Keep moving while 
    // the two pointers
    // don't become same. 
    while ($a < $b)
    {
        if (knows($a, $b))
            $a++;
        else
            $b--;
    }
  
    // Check if a is actually
    // a celebrity or not
    for ( $i = 0; $i < $n; $i++)
    {
        // If any person doesn't 
        // know 'a' or 'a' doesn't 
        // know any person, return -1
        if ( ($i != $a) and
                (knows($a, $i) || 
                !knows($i, $a)) )
            return -1;
    }
  
    return $a;
}
  
// Driver code
$n = 4;
$id = findCelebrity($n);
if($id == -1)
echo "No celebrity" ;
else
echo "Celebrity ID " , $id;
  
// This code is contributed by anuj_67.
?>

chevron_right


Output : 

Celebrity ID 2
  • Complexity Analysis: 
    • Time Complexity: O(n). 
      Total number of comparisons 2(N-1), so the time complexity is O(n).
    • Space Complexity : O(1). 
      No extra space is required.

  1. Write code to find celebrity. Don’t use any data structures like graphs, stack, etc… you have access to N and HaveAcquaintance(int, int) only.
  2. Implement the algorithm using Queues. What is your observation? Compare your solution with Finding Maximum and Minimum in an array and Tournament Tree. What are minimum number of comparisons do we need (optimal number of calls to HaveAcquaintance())?

 

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up