1. 题目描述 Problem Description

Leetcode 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.

2. 题目解析(参考了Prof. Sarrafzadeh 180讲的内容)

首先题目定义了:如果一个人A是名人,那么其他的n-1个人都认识A,而且A不认识其他的n-1个人。这题的目标是要从n个人中找出其中的名人,如果没有,则告知其中没有名人。我们可以调用knows(a,b)函数来询问a是否认识b,而我们要尽量少调用这个函数。

这题的关键是理解题意,题意其实比较容易理解错,所以有几个小问题可以帮大家理解:

(1)n个人中最多可以有几个名人?

答案:是1个。如果这n个人中有2个名人分别为A和B,那么按照定义,如果一个人A是名人,那么其他的n-1个人都认识A,而且A不认识其他的n-1个人,这也就是说A不认识B。但与此同时我们又定义了如果一个人B是名人,那么其他的n-1个人都认识B,那么A也应该认识B。这就产生了 contradiction了。因此其中不可以有2个或2个以上的名人。

(2) 如果其他n-1个人都认识A,但是A认识了n-1个人中其中一个人,那么A还是名人吗?

答案:不是的。

(3) 如果A不认识其他的n-1个人,但是n-1个人中有人不认识A,那么A还是名人吗?

答案:不是的。

-

这题最直接的想法应该是暴力,但是暴力的复杂度是多少呢?对于每个人我们需要询问:

(1) 他是否认识剩下的n-1个人: 最坏的情况需要调用knows(a,b)函数n-1次

(2) 剩下的n-1个人是否认识他:最坏的情况需要调用knows(a,b)函数n-1次

有的可能会重复,但是总体来说需要询问的次数是$\frac{n(n-1)}{2}$。即时间复杂度为 O($n^2$)

-

有没有办法优化算法?

如果我们从n个人中任意挑两个人a,b出来,询问啊是否认识b,那么只有两种情况:

(1)a认识b:那么a肯定不是名人。

(2)b认识a:那么b肯定不是名人。

所以任何一种情况,我们都可以排除掉2个人中的1一个人。如果我们不断地重复的这个过程,直到只剩下一个人,那么我们会做n-1次对比。而剩下这个人是唯一可能成为名人的人,那么我们需要询问剩下的n-1个人是否认识他,也需要询问他是否认识剩下的n-1个人。

因此我们一共需要询问3(n-1)次——时间复杂度为O($n$)。

3. Python 实现

 # The knows API is already defined for you.
 # @param a, person a
 # @param b, person b
 # @return a boolean, whether a knows b
 # def knows(a, b):

 class Solution(object):
     def findCelebrity(self, n):
         """
         :type n: int
         :rtype: int
         """
         if n == 0:
             return -1
         curr_stay = 0
         for i in range(1, n):
             if knows(curr_stay, i):
                 curr_stay = i
         for i in range(0, n):
             if i == curr_stay:
                 continue
             if knows(curr_stay, i):
                 return -1
             if not knows(i, curr_stay):
                 return -1
         return curr_stay
             

名人问题 算法解析与Python 实现 O(n) 复杂度 (以Leetcode 277. Find the Celebrity为例)的更多相关文章

  1. DeepFM算法解析及Python实现

    1. DeepFM算法的提出 由于DeepFM算法有效的结合了因子分解机与神经网络在特征学习中的优点:同时提取到低阶组合特征与高阶组合特征,所以越来越被广泛使用. 在DeepFM中,FM算法负责对一阶 ...

  2. GBDT+LR算法解析及Python实现

    1. GBDT + LR 是什么 本质上GBDT+LR是一种具有stacking思想的二分类器模型,所以可以用来解决二分类问题.这个方法出自于Facebook 2014年的论文 Practical L ...

  3. FM算法解析及Python实现

    1. 什么是FM? FM即Factor Machine,因子分解机. 2. 为什么需要FM? 1.特征组合是许多机器学习建模过程中遇到的问题,如果对特征直接建模,很有可能会忽略掉特征与特征之间的关联信 ...

  4. Bayesian Personalized Ranking 算法解析及Python实现

    1. Learning to Rank 1.1 什么是排序算法 为什么google搜索 ”idiot“ 后,会出现特朗普的照片? “我们已经爬取和存储了数十亿的网页拷贝在我们相应的索引位置.因此,你输 ...

  5. FFM算法解析及Python实现

    1. 什么是FFM? 通过引入field的概念,FFM把相同性质的特征归于同一个field,相当于把FM中已经细分的feature再次进行拆分从而进行特征组合的二分类模型. 2. 为什么需要FFM? ...

  6. [leetcode]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 o ...

  7. [LeetCode] 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 o ...

  8. [leetcode]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 o ...

  9. python常见排序算法解析

    python——常见排序算法解析   算法是程序员的灵魂. 下面的博文是我整理的感觉还不错的算法实现 原理的理解是最重要的,我会常回来看看,并坚持每天刷leetcode 本篇主要实现九(八)大排序算法 ...

随机推荐

  1. Oracle数据库新装之后出现的监听程序无法正常启动和运行(Oracle-12514)

    修改安装目录下的配置文件      比如:F:\app\admin-PC\product\11.2.0\dbhome_1\network\admin\ 修改这个目录下的listener.ora和tns ...

  2. 【Java】使用Atomic变量实现锁

    Atomic原子操作 在 Java 5.0 提供了 java.util.concurrent(简称JUC)包,在此包中增加了在并发编程中很常用的工具类 Java从JDK1.5开始提供了java.uti ...

  3. UDP实现网络通信程序

    VC6.0创建基于UDP协议的网络聊天程序 只有一个工程UDP,服务器和客户端都是这个工程,因为UDP中C/S区分不强化 只讲关键部分,避免累赘 1.为对话框添加控件 2.为控件绑定变量和消息函数 启 ...

  4. 纯js轮播图练习-2,js+css旋转木马层叠轮播

    基于css3的新属性,加上js的操作,让现在js轮播图花样越来越多. 而现在出现的旋转木马层叠轮播的轮播图样式,却是得到了很多人都喜爱和投入使用. 尤其是在各大软件中,频繁的出现在大家的眼里,在web ...

  5. html5 video获取当前时间和视频总时间长度

    html: <video id="video-active" class="video-active" width="640" hei ...

  6. centos install rabbitmq

    安装rabbitmq 需要环境上有erlang,没有安装的可以参照下面的内容进行安装: https://www.erlang-solutions.com/resources/download.html ...

  7. C语言:一个数组中只有两个数字是出现一次

    //1.一个数组中只有两个数字是出现一次, //其他所有数字都出现了两次. //找出这两个数字,编程实现.a //^=单独两个数的^结果 //单独出现的两个数不同位的标记 //position: ^结 ...

  8. go内建容器-Map

    1.基础定义 golang中的map如同它的函数一样"纯粹",map就是用来存储键值对的容器,别管什么哈希不哈希的(底层已实现),用就行 //创建一个map m := map[st ...

  9. Python CSV模块简介

    Table of Contents 1. CSV 1.1. 简介 1.2. 字典方式地读写 1.3. 其它 2. 参考资料 CSV csv文件格式是一种通用的电子表格和数据库导入导出格式.最近我调用R ...

  10. 北京Uber优步司机奖励政策(1月17日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...