​LeetCode刷题实战277:搜寻名人

算法的重要性,我就不多说了吧,想去大厂,就必须要经过基础知识和业务逻辑面试+算法面试。所以,为了提高大家的算法能力,这个公众号后续每天带大家做一道算法题,题目就从LeetCode上面选 !

今天和大家聊的问题叫做 搜寻名人,我们先来看题面:
https://leetcode-cn.com/problems/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.

假设你是一个专业的狗仔,参加了一个 n 人派对,其中每个人被从 0 到 n – 1 标号。
在这个派对人群当中可能存在一位 “名人”。
所谓 “名人” 的定义是:其他所有 n – 1 个人都认识他/她,而他/她并不认识其他任何人。

现在你想要确认这个 “名人” 是谁,或者确定这里没有 “名人”。
而你唯一能做的就是问诸如 “A 你好呀,请问你认不认识 B呀?” 的问题,以确定 A 是否认识 B。
你需要在(渐近意义上)尽可能少的问题内来确定这位 “名人” 是谁(或者确定这里没有 “名人”)。

在本题中,你可以使用辅助函数 bool knows(a, b) 获取到 A 是否认识 B。请你来实现一个函数 int findCelebrity(n)。

派对最多只会有一个 “名人” 参加。
若 “名人” 存在,请返回他/她的编号;若 “名人” 不存在,请返回 -1。


示例

​LeetCode刷题实战277:搜寻名人

输入: graph = [
  [1,1,0],
  [0,1,0],
  [1,1,1]
]
输出: 1

解析: 有编号分别为 0、1 和 2 的三个人。
graph[i][j] = 1 代表编号为 i 的人认识编号为 j 的人,
而 graph[i][j] = 0 则代表编号为 i 的人不认识编号为 j 的人。
“名人” 是编号 1 的人,因为 0 和 2 均认识他/她,但 1 不认识任何人。


解题

首先明确名人的特点,即从任意一个人出发,顺着箭头的方向,箭头的末端我们一定可以找到一个“候选名人”,然后再for遍历一次,判断此“候选名人”是不是真正的名人即可。

其实蛮简单的,答案如下:

/* 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;
        //每一次比较只有两种情况,knows(a, b)是true的话,那么a肯定不是candidate; knows(a, b)是false的话,那么b肯定不是candidate. 所以一直比较到最后会留下一个candidate,然后我们再验证这个是不是正解。
        for (int i = 1; i < n; i++) {
            if (knows(candidate, i)) {
                candidate = i;
            }
        }
        for (int i = 0; i < n; i++) {
            if (candidate != i && (knows(candidate, i) || !knows(i, candidate))) {
                return -1;
            }
        }
        return candidate;
    }
}


好了,今天的文章就到这里,如果觉得有所收获,请顺手点个在看或者转发吧,你们的支持是我最大的动力 。

上期推文:

LeetCode1-260题汇总,希望对你有点帮助!
LeetCode刷题实战261:以图判树
LeetCode刷题实战262:行程和用户
LeetCode刷题实战263:丑数
LeetCode刷题实战264:丑数 II
LeetCode刷题实战265:粉刷房子II
LeetCode刷题实战266:回文排列
LeetCode刷题实战267:回文排列II
LeetCode刷题实战268:丢失的数字
LeetCode刷题实战269:火星词典
LeetCode刷题实战270:最接近的二叉搜索树值
LeetCode刷题实战271:字符串的编码与解码
LeetCode刷题实战272:最接近的二叉搜索树值 II
LeetCode刷题实战273:整数转换英文表示

LeetCode刷题实战274:H指数

LeetCode刷题实战275:H 指数 II

LeetCode刷题实战276:栅栏涂色


​LeetCode刷题实战277:搜寻名人

原创文章,作者:栈长,如若转载,请注明出处:https://www.cxyquan.com/11893.html

发表评论

登录后才能评论

联系我们

400-800-8888

在线咨询:点击这里给我发消息

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息