[抄题]:
假设你和 n
个人在一个聚会中(标记为 0
到 n - 1
),其中可能存在一个名人。名人的定义是所有其他 n - 1
人都认识他/她,但他/她不知道任何一个。
现在你想要找出这个名人是谁或者验证这个名人不存在。你唯一可以做的事情就是提出如下问题:“你好,A,你认识B吗?” 来获取A是否认识B。您需要通过询问尽可能少的问题(以渐近的意义)来找出名人是谁(或验证其不存在)。
你得到一个辅助函数 bool know(a,b)
,它会告诉你A是否知道B.实现一个函数 int findCelebrity(n)
,你的函数应该使 knows
的调用次数最少。
[暴力解法]:
n个人问n-1遍
时间分析:true的时候可以排除一个人,false的时候可以排除一个人。从而降低复杂度到n-1 + 1 = n
空间分析:
[思维问题]:
不知两两比较的时候是不是要用i i+1,感觉换起来很麻烦:定义一个ans,扫一遍i的过程中改变唯一的结果ans即可
[一句话思路]:
[输入量]:空: 正常情况:特大:特小:程序里处理到的特殊情况:异常情况(不合法不合理的输入):
[画图]:
[一刷]:
- 不知道为啥最后还要检验是不是名人:防止两人互相认识的特殊情况(要考虑到)
[二刷]:
- 最后检查的时候,先假设i不是ans,才能二者之间对比检验。i == ans时不要想着引入第三个变量来检验。
[三刷]:
[四刷]:
[五刷]:
[五分钟肉眼debug的结果]:
[总结]:
[复杂度]:Time complexity: O(n) Space complexity: O(1)
[英文数据结构或算法,为什么不用别的数据结构或算法]:
api函数就当一般函数,拿来就用就行
[其他解法]:
[Follow Up]:
[LC给出的题目变变变]:
[代码风格] :
/* The knows API is defined in the parent class Relation. boolean knows(int a, int b); */ public class Solution extends Relation { /** * @param n a party with n people * @return the celebrity's label or -1 */ public int findCelebrity(int n) { //find int ans = 0; for (int i = 1; i < n; i++) { if (knows(ans, i) == true) { ans = i; } } //check for (int i = 0; i < n; i++) {//suppose not if (i != ans && !knows(i, ans)) { return -1; } if (i != ans && knows(ans, i)) { return -1; } } return ans;// } }