The Celebrity Problem


The Celebrity Problem | GeeksforGeeks
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 minimum number of questions.

We have following observation based on elimination technique (Refer Polya’s How to Solve It book).
  • If A knows B, then A can’t be celebrity. Discard A, and B may be celebrity.
  • If A doesn’t know B, then B can’t be celebrity. Discard B, and A may be celebrity.
  • Repeat above two steps till we left with only one person.
  • Ensure the remained person is celebrity. (Why do we need this step?)
We can use stack to verity celebrity.
  1. Push all the celebrities into a stack.
  2. Pop off top two persons from the stack, discard one person based on return status of HaveAcquaintance(A, B).
  3. Push the remained person onto stack.
  4. Repeat step 2 and 3 until only one person remains in the stack.
  5. Check the remained person in stack doesn’t have acquaintance with anyone else.
We will discard N elements utmost (Why?). If the celebrity is present in the party, we will callHaveAcquaintance() 3(N-1) times. 

http://blog.csdn.net/fightforyourdream/article/details/17410993
我们把人编号,比如从1 到 N。 
我们考虑最坏情况:你问每一个人是否认识 X ,如果大家都认识,那么 X 一定是名人,如果其中一个人说不认识,那么那个人一定不是名人。因为 X 的范围是 1 到 N, 所以,在最坏情况下,我们 要问 (N - 1)* N 个问题。

但是,有一种更好的方法。我们从1开始,依次问他是否认识他的下一个,比如 2, 如果 1 说认识,那么 1 一定不是名人,2 有可能是名人; 如果1 说不认识,2 一定不是名人,1 却有可能是名人。这是这个方法巧的地方。所以,不管1 回答是还是不是,我们都可以确定其中一个不是名人,然后,我们继续问 可能是名人那一位 是否认识 3, 然后依次下去,直到第 N 个人。这样我们就可以只要问 (N - 1) 个问题就可以把名人找出来。
https://github.com/monkeylyf/interviewjam/blob/master/graph/facebook_Celebrity_Problem.java
  public void solve() {
int[][] acquiantance = new int[][] { {0, 0, 1, 0},
 {0, 0, 1, 0},
 {0, 0, 0, 0},
 {0, 0, 1, 0}
};
System.out.println(howIsCelebrity(acquiantance, acquiantance.length));

  }

  public int howIsCelebrity(int[][] acquiantance, int n) {
Stack<Integer> s = new Stack<Integer>();

int id = 0;

while (id < n) {
 s.push(id);
 ++id;
}

int a = s.pop();
int b = s.pop();

while (s.size() != 1) {
 if (haveAcquiantance(acquiantance, a, b)) {
// a knows b and a is not the celebrity. Update a.
a = s.pop();
 } else {
// a does not know b so b cannot be the celebrity. Update b
b = s.pop();
 }
}

// With one element in stack, check if that is the celebrity.
int candidate = s.pop();

if (haveAcquiantance(acquiantance, candidate, a)) {
 candidate = a;
}

if (haveAcquiantance(acquiantance, candidate, b)) {
 candidate = b;
}


for (int i = 0; i < n; ++i) {
 if (i == candidate) {
continue;
 }
 if (haveAcquiantance(acquiantance, candidate, i) || !haveAcquiantance(acquiantance, i, candidate)) {
return -1;
 }
}

return candidate;
  }

  public boolean haveAcquiantance(int[][] acquiantance, int a, int b) {
return acquiantance[a][b] == 1;
  }

int CelebrityUsingStack(int size)
{
   // Handle trivial case of size = 2
   list<int> stack; // Careful about naming
   int i;
   int C; // Celebrity
   i = 0;
   while( i < size )
   {
      stack.push_back(i);
      i = i + 1;
   }
   int A = stack.back();
   stack.pop_back();
   int B = stack.back();
   stack.pop_back();
   while( stack.size() != 1 )
   {
      if( HaveAcquiantance(A, B) )
      {
         A = stack.back();
         stack.pop_back();
      }
      else
      {
         B = stack.back();
         stack.pop_back();
      }
   }
   // Potential candidate?
   C = stack.back();
   stack.pop_back();
   // Last candidate was not examined, it leads one excess comparison (optimise)
   if( HaveAcquiantance(C, B) )
      C = B;
   if( HaveAcquiantance(C, A) )
      C = A;
   // I know these are redundant,
   // we can simply check i against C
   i = 0;
   while( i < size )
   {
      if( C != i )
      stack.push_back(i);
      i = i + 1;
   }
   while( !stack.empty() )
   {
      i = stack.back();
      stack.pop_back();
      // C must not know i
      if( HaveAcquiantance(C, i) )
         return -1;
      // i must know C
      if( !HaveAcquiantance(i, C) )
         return -1;
   }
   return C;
}
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 withFinding Maximum and Minimum in an array and Tournament Tree. What are minimum number of comparisons do we need (optimal number of calls to HaveAcquaintance())?
http://shibaili.blogspot.com/2015/09/day-129-277-find-celebrity.html
对a做检测,如果a认识b || b不认识a,a就不会是celebrity
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// Forward declaration of the knows API.
bool knows(int a, int b);
class Solution {
public:
    int findCelebrity(int n) {
        for (int a = 0; a < n; a++) {
            int b = 0;
            for (; b < n; b++) {
                if (a == b) continue;
                if (knows(a,b) || !knows(b,a)) {
                    break;
                }
            }
            if (b == n) return a;
        }
         
        return -1;
    }
};
第一个循坏对can进行挑选,如果i不认识can,则说明can一定不是celebrity。如果i认识can,能说明i一定不是celebrity 
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Forward declaration of the knows API.
bool knows(int a, int b);
class Solution {
public:
    int findCelebrity(int n) {
        int can = 0;
        for (int i = 1; i < n; i++) {
            if (!knows(i,can)) {
                can = i;
            }
        }
         
        for (int i = 0; i < n; i++) {
            if (i == can) continue;
            if (!knows(i,can) || knows(can,i)) return -1;
        }
         
        return can;
    }
};
http://www.zrzahid.com/find-influencer-or-celebrity/
A celebrity/influencer is a person who doesn’t know anybody but is known to or followed by everybody. Given N peoples and a matrix for known or following information then find the celebrity or influencer among the group of N peoples.
Formally speaking, Given a matrix of following between N users (with ids from 0 to N-1):
* following[i][j] == true iff user i is following user j
* thus following[i][j] doesn’t imply following[j][i].
* Let’s also agree that followingMatrix[i][i] == false
*
* Influencer is a user who is:
* – followed by everyone else and
* – not following anyone himself
*
* Find an Influencer by a given matrix of following,
* or return -1 if there is no Influencer in this group.
For example, Lets suppose we have N=5 peoples {A,B,C,D,E} and the following matrix is as follows –
following[0][3] = 1;
following[0][1] = 1;
following[1][3] = 1;
following[1][0] = 1;
following[1][4] = 1;
following[4][3] = 1;
following[2][3] = 1;
following[2][4] = 1;
then clearly 3 is celebrity.

We can build a directed graph and then find the single vertex that has out degree 0 but in degree = N-1.
Screen Shot 2015-11-03 at 2.56.46 AM
Computing in-degree and out-degree of a directed graph will take O(n^2) time. Can we do better? Note that, we can easily proof that there should be only one celebrity c with the two following properties –
1. Everybody knows c
2. c doesn't know anybody        
So, we can compute the celebrity in O(n) time by testing each person for the above properties. We can select a person c as a candidate celebrity and then test if c is indeed a celebrity by testing with next person. If the next person doesn’t know (or follow) the current candidate (or influencer) or the candidate knows the next person then the next person may be the celebrity. We can choose such a candidate and then test if all other person knows the candidate c and the candidate c doesn’t know anybody. If any of these properties fail we say there is no such celebrity (or influencer). The overall complexity is O(n).
public static int influencer(int[][] following){
 int influencer = 0;
 
 //find the candidate influencer by testing each person i
 //a person i may be a candidate influencer if s/he follows nobody or som
 for(int i = 1; i < following.length; i++){
  if(following[i][influencer] == 0 || following[influencer][i] == 1){
   influencer = i;
  }
 }
 
 //verify that the candidate influencer is indeed an influencer
 for(int i = 0; i < following.length; i++){
  if(i == influencer){
   continue;
  }
  //to be influencer he/she shouldn't follow anybody and there should be nobody else who doesn't follw him/her
  if(following[i][influencer] == 0 || following[influencer][i] == 1){
   return -1;
  }
 }
 
 return influencer;
}

https://lina.bitcron.com/post/code/2018-summer-fb-intern-mian-jing
collection of objects,只能两两判断大小。只有“大”和“小”, 没有”等“。 然后也没有transitivity,也就是A > B && B > C 不能推出A > C。 类似石头剪刀布。要求找出max, max的定义是比其他所有都大。Find celebrity 变种: max 大于所有数
 public Object findMax(List<Object> list){
    Object candidate = list.get(0);
    for(Object x : list)
    {   if(x>candidate){
            candidate = x;
         }
    }
    for(Object x : list){
        if(x>=candidate&&x!=candidate){
            return null;
        }
    }
    return candidate;
 }
Read full article from The Celebrity Problem | GeeksforGeeks

Labels

LeetCode (1432) GeeksforGeeks (1122) LeetCode - Review (1067) Review (882) Algorithm (668) to-do (609) Classic Algorithm (270) Google Interview (237) Classic Interview (222) Dynamic Programming (220) DP (186) Bit Algorithms (145) POJ (141) Math (137) Tree (132) LeetCode - Phone (129) EPI (122) Cracking Coding Interview (119) DFS (115) Difficult Algorithm (115) Lintcode (115) Different Solutions (110) Smart Algorithm (104) Binary Search (96) BFS (91) HackerRank (90) Binary Tree (86) Hard (79) Two Pointers (78) Stack (76) Company-Facebook (75) BST (72) Graph Algorithm (72) Time Complexity (69) Greedy Algorithm (68) Interval (63) Company - Google (62) Geometry Algorithm (61) Interview Corner (61) LeetCode - Extended (61) Union-Find (60) Trie (58) Advanced Data Structure (56) List (56) Priority Queue (53) Codility (52) ComProGuide (50) LeetCode Hard (50) Matrix (50) Bisection (48) Segment Tree (48) Sliding Window (48) USACO (46) Space Optimization (45) Company-Airbnb (41) Greedy (41) Mathematical Algorithm (41) Tree - Post-Order (41) ACM-ICPC (40) Algorithm Interview (40) Data Structure Design (40) Graph (40) Backtracking (39) Data Structure (39) Jobdu (39) Random (39) Codeforces (38) Knapsack (38) LeetCode - DP (38) Recursive Algorithm (38) String Algorithm (38) TopCoder (38) Sort (37) Introduction to Algorithms (36) Pre-Sort (36) Beauty of Programming (35) Must Known (34) Binary Search Tree (33) Follow Up (33) prismoskills (33) Palindrome (32) Permutation (31) Array (30) Google Code Jam (30) HDU (30) Array O(N) (29) Logic Thinking (29) Monotonic Stack (29) Puzzles (29) Code - Detail (27) Company-Zenefits (27) Microsoft 100 - July (27) Queue (27) Binary Indexed Trees (26) TreeMap (26) to-do-must (26) 1point3acres (25) GeeksQuiz (25) Merge Sort (25) Reverse Thinking (25) hihocoder (25) Company - LinkedIn (24) Hash (24) High Frequency (24) Summary (24) Divide and Conquer (23) Proof (23) Game Theory (22) Topological Sort (22) Lintcode - Review (21) Tree - Modification (21) Algorithm Game (20) CareerCup (20) Company - Twitter (20) DFS + Review (20) DP - Relation (20) Brain Teaser (19) DP - Tree (19) Left and Right Array (19) O(N) (19) Sweep Line (19) UVA (19) DP - Bit Masking (18) LeetCode - Thinking (18) KMP (17) LeetCode - TODO (17) Probabilities (17) Simulation (17) String Search (17) Codercareer (16) Company-Uber (16) Iterator (16) Number (16) O(1) Space (16) Shortest Path (16) itint5 (16) DFS+Cache (15) Dijkstra (15) Euclidean GCD (15) Heap (15) LeetCode - Hard (15) Majority (15) Number Theory (15) Rolling Hash (15) Tree Traversal (15) Brute Force (14) Bucket Sort (14) DP - Knapsack (14) DP - Probability (14) Difficult (14) Fast Power Algorithm (14) Pattern (14) Prefix Sum (14) TreeSet (14) Algorithm Videos (13) Amazon Interview (13) Basic Algorithm (13) Codechef (13) Combination (13) Computational Geometry (13) DP - Digit (13) LCA (13) LeetCode - DFS (13) Linked List (13) Long Increasing Sequence(LIS) (13) Math-Divisible (13) Reservoir Sampling (13) mitbbs (13) Algorithm - How To (12) Company - Microsoft (12) DP - Interval (12) DP - Multiple Relation (12) DP - Relation Optimization (12) LeetCode - Classic (12) Level Order Traversal (12) Prime (12) Pruning (12) Reconstruct Tree (12) Thinking (12) X Sum (12) AOJ (11) Bit Mask (11) Company-Snapchat (11) DP - Space Optimization (11) Dequeue (11) Graph DFS (11) MinMax (11) Miscs (11) Princeton (11) Quick Sort (11) Stack - Tree (11) 尺取法 (11) 挑战程序设计竞赛 (11) Coin Change (10) DFS+Backtracking (10) Facebook Hacker Cup (10) Fast Slow Pointers (10) HackerRank Easy (10) Interval Tree (10) Limited Range (10) Matrix - Traverse (10) Monotone Queue (10) SPOJ (10) Starting Point (10) States (10) Stock (10) Theory (10) Tutorialhorizon (10) Kadane - Extended (9) Mathblog (9) Max-Min Flow (9) Maze (9) Median (9) O(32N) (9) Quick Select (9) Stack Overflow (9) System Design (9) Tree - Conversion (9) Use XOR (9) Book Notes (8) Company-Amazon (8) DFS+BFS (8) DP - States (8) Expression (8) Longest Common Subsequence(LCS) (8) One Pass (8) Quadtrees (8) Traversal Once (8) Trie - Suffix (8) 穷竭搜索 (8) Algorithm Problem List (7) All Sub (7) Catalan Number (7) Cycle (7) DP - Cases (7) Facebook Interview (7) Fibonacci Numbers (7) Flood fill (7) Game Nim (7) Graph BFS (7) HackerRank Difficult (7) Hackerearth (7) Inversion (7) Kadane’s Algorithm (7) Manacher (7) Morris Traversal (7) Multiple Data Structures (7) Normalized Key (7) O(XN) (7) Radix Sort (7) Recursion (7) Sampling (7) Suffix Array (7) Tech-Queries (7) Tree - Serialization (7) Tree DP (7) Trie - Bit (7) 蓝桥杯 (7) Algorithm - Brain Teaser (6) BFS - Priority Queue (6) BFS - Unusual (6) Classic Data Structure Impl (6) DP - 2D (6) DP - Monotone Queue (6) DP - Unusual (6) DP-Space Optimization (6) Dutch Flag (6) How To (6) Interviewstreet (6) Knapsack - MultiplePack (6) Local MinMax (6) MST (6) Minimum Spanning Tree (6) Number - Reach (6) Parentheses (6) Pre-Sum (6) Probability (6) Programming Pearls (6) Rabin-Karp (6) Reverse (6) Scan from right (6) Schedule (6) Stream (6) Subset Sum (6) TSP (6) Xpost (6) n00tc0d3r (6) reddit (6) AI (5) Abbreviation (5) Anagram (5) Art Of Programming-July (5) Assumption (5) Bellman Ford (5) Big Data (5) Code - Solid (5) Code Kata (5) Codility-lessons (5) Coding (5) Company - WMware (5) Convex Hull (5) Crazyforcode (5) DFS - Multiple (5) DFS+DP (5) DP - Multi-Dimension (5) DP-Multiple Relation (5) Eulerian Cycle (5) Graph - Unusual (5) Graph Cycle (5) Hash Strategy (5) Immutability (5) Java (5) LogN (5) Manhattan Distance (5) Matrix Chain Multiplication (5) N Queens (5) Pre-Sort: Index (5) Quick Partition (5) Quora (5) Randomized Algorithms (5) Resources (5) Robot (5) SPFA(Shortest Path Faster Algorithm) (5) Shuffle (5) Sieve of Eratosthenes (5) Strongly Connected Components (5) Subarray Sum (5) Sudoku (5) Suffix Tree (5) Swap (5) Threaded (5) Tree - Creation (5) Warshall Floyd (5) Word Search (5) jiuzhang (5)

Popular Posts