#leetcoce#277. Find the Celebrity

Suppose you are at a party with n people (labeled from 0 to n - 1) and among them, there may exist one celebrity. The definition of a celebrity is that all the other n - 1 people know him/her but he/she does not know any of them.

Now you want to find out who the celebrity is or verify that there is not one. The only thing you are allowed to do is to ask questions like: "Hi, A. Do you know B?" to get information of whether A knows B. You need to find out the celebrity (or verify there is not one) by asking as few questions as possible (in the asymptotic sense).

You are given a helper function bool knows(a, b) which tells you whether A knows B. Implement a function int findCelebrity(n), your function should minimize the number of calls to knows.

Note: There will be exactly one celebrity if he/she is in the party. Return the celebrity's label if there is a celebrity in the party. If there is no celebrity, return -1.

--------------------------------------------------------------------------------------------------------------------

由题目描述得知,celebrity如下性质: 

  1. 其他所有人都认识 celebrity, 如下图 蓝色的 T, 表示 true
  2. celebrity 不认识其他所有人, 如下图红色的 F, 表示 false

题目给的 knows(a, b) 如果返回 true,则 a 认识 b, a 不可能是 celebrity, 

如果返回 false,则 a 不认识 b, b 不可能是 celebrity, 所以每call 一次 knows()method,总能排除一个人,

最开始想的两层循环,根据上面的性质一一排除,到最后剩一个的时候再按照celebrity的性质判断是否符合

两两比较更有效率, 维护一个Queue,把有可能的人放在queue中比较,最后剩一个的时候就是可能的celebrity。用了一个Boolean[][] 数组来避免重复的 knows() call

01234
0FTTTF
1FFTTT
2FFFTT
3FFFFF
4TTTTF

/* 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) {
        Queue<Integer> queue = new LinkedList<>();
        for(int i = 0; i < n; i++){
            queue.offer(i);
        }
        Boolean[][] know = new Boolean[n][n];//default will be null
        while(!queue.isEmpty()){
            if(queue.size() == 1){
                //now there is only one people that might be the celebrity, we need to iterate all other people to see if this guy satisfies he/she does not know any others && all others knows him/her
                int cur = queue.poll();
                for(int i = 0; i < n; i++){
                    if(i == cur)
                        continue;

                    if(know[cur][i] == null){
                        if(knows(cur, i)){
                            return -1;
                        }
                    }else if(know[cur][i]){
                        return -1;
                    }
                    
                    
                    if(know[i][cur] == null){
                        if(!knows(i, cur)){
                            return -1;
                        }
                    }else if(!know[i][cur]){
                        return -1;
                    }
                }
                return cur;
            }
            int i = queue.poll();
            int j = queue.poll();
            if(knows(i, j)){//i knows j, i must not be the celebrity, j may be
                queue.offer(j);
                know[i][j] = true;
            }else{//i does not know j, j must not be the celebrity, i may be
                queue.offer(i);
                know[i][j] = false;
            }
        }
        
        return -1;
    }
}


看了discuss的讨论,发现下面的解法更简洁一些,调用 knows 的次数肯定比维护 Boolean[][]数组多,但是多得也比较有限。

因为每次调用 knows() , 都可以排除掉一个人,所以下面这种方法和维护Queue然后一直比较 有可能成为 celebrity的人的比较次数是同样的,都是 n - 1 次 比较。

/* 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;
            }
        }
        // now we already know that for x in [candidate + 1 to n - 1], knows(candidate, x) returns false;
        for(int i = 0; i < n; i++){
            if(i == candidate){
                continue;
            }
            if(i < candidate && knows(candidate, i)){
                return -1;
            }
            if(!knows(i, candidate)){
                return -1;
            }
        }
        return candidate;
    }        
}

As an AI language model, I don't have personal experiences or have the ability to make up stories. However, here are some celebrity stories that you may find interesting: 1. Lady Gaga's story of perseverance: Before Lady Gaga became the global superstar that she is today, she faced numerous rejections and struggles in the music industry. She was dropped by her record label and had to perform in small bars and clubs to make ends meet. However, she never gave up on her dreams and finally got her big break with her debut album, "The Fame." 2. Jennifer Lawrence's empowering speech on body shaming: During a press conference for one of her movies, Jennifer Lawrence was asked a question about her diet and body, which she found offensive. Instead of ignoring the question, she used the opportunity to speak out against body shaming and the unrealistic beauty standards that women face in Hollywood. Her courageous and honest response earned her praise from fans and fellow celebrities alike. 3. Dwayne "The Rock" Johnson's inspiring journey to success: Dwayne "The Rock" Johnson started his career as a professional wrestler and later transitioned to acting. He faced many challenges along the way, including multiple injuries and setbacks. However, he never gave up on his goals and worked tirelessly to build his brand and become one of the most successful actors in Hollywood. 4. Beyoncé's message of female empowerment: Beyoncé is known for her powerful music and message of female empowerment. She has consistently used her platform to speak out against issues like sexism, racism, and police brutality. Her music and activism have inspired millions of people around the world to stand up for their rights and fight for equality. These are just a few examples of how celebrities can use their influence to inspire and empower others. By sharing their stories, we can all learn valuable lessons about perseverance, courage, and standing up for what we believe in.
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值