[LeetCode#277] Find the Celebrity
Problem:
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
.
Analysis:
Even though the problem is not hard, the efficiency could vary a lot, and the concisness of the code could also vary a lot!!!
I have explored following mistakes and implementation until I reach the final solution. Mistake 1:
Put return in "if-else". Note this is a very common mistake, you should always guanratee a default return at last. if (candidates.size() != 1) {
return -1;
} else{
for (int i : candidates)
return i;
} Line 27: error: missing return statement Mistake 2: Modify sets when iterate on it.
public class Solution extends Relation {
public int findCelebrity(int n) {
if (n <= 0)
throw new IllegalArgumentException("n is invalid");
HashSet<Integer> candidates = new HashSet<Integer> ();
for (int i = 0; i < n; i++)
candidates.add(i);
for (int i = 0; i < n; i++) {
for (int j : candidates) {
if (i != j) {
if (knows(i, j))
candidates.remove(i);
else
candidates.remove(j);
}
}
}
if (candidates.size() == 1) {
for (int i : candidates)
return i;
}
return -1;
}
} Runtime Error Message:
Line 26: java.util.ConcurrentModificationException Note: this is absolutely allowed!!! A way to avoid this is to use a HashSet to record all the elements you want to remove. When you finish the iteration, then you can remove those elements through "set.removeAll()" method to remove them. public class Solution extends Relation {
public int findCelebrity(int n) {
if (n <= 0)
throw new IllegalArgumentException("n is invalid");
HashSet<Integer> candidates = new HashSet<Integer> ();
HashSet<Integer> excludes = new HashSet<Integer> ();
for (int i = 0; i < n; i++)
candidates.add(i);
for (int i = 0; i < n; i++) {
for (int j : candidates) {
if (i != j) {
if (knows(i, j)) {
excludes.add(i);
} else{
excludes.add(j);
}
}
}
candidates.removeAll(excludes);
}
if (candidates.size() == 1) {
for (int i : candidates)
return i;
}
return -1;
}
} Input:
0 knows 1; 1 knows 0.
Output:
1
Expected:
-1 As you can see from the error notification, the above solution could still be wrong. The problem is that even there maybe only "1 element" left in the candidates set, it may not be the answer. case 1: iff such celebrity exist, there must one element left.
case 2: iff not exist, there also could be elements left in the Set, thus we have to do the final check to resure the left element is a celebrity/ Update:
public class Solution extends Relation {
public int findCelebrity(int n) {
if (n <= 0)
throw new IllegalArgumentException("n is invalid");
HashSet<Integer> candidates = new HashSet<Integer> ();
HashSet<Integer> excludes = new HashSet<Integer> ();
for (int i = 0; i < n; i++)
candidates.add(i);
for (int i = 0; i < n; i++) {
for (int j : candidates) {
if (i != j) {
if (knows(i, j)) {
excludes.add(i);
} else{
excludes.add(j);
}
}
}
candidates.removeAll(excludes);
}
for (int i : candidates) {
for (int j = 0; j < n; j++) {
if (i != j) {
if (knows(i, j) || !knows(j, i))
return -1;
}
}
}
for (int i : candidates)
return i;
return -1;
}
} We have used two HashSets in the above solution, and for each non-repeative comparision, we could eliminate one candidate out. Thus for the above code the time complexity is actually O(n). Actually, using above conclusion, we could write the code into a more elegant way. We could use a stack to guarantee:
1. if there is a celebrity, it must remain in the stack(as long as there is an element)
2. there is no repeatitive comparision among candidate. We know for each comparision, we must be able to eliminate one element out.
1. iff A knows B, A must not the celebrity, since celebrity knows no one.
2. iff A did not know B, B must not the celebrity, since everyone knows celebrity. while (stack.size() > 1) {
int i = stack.pop();
int j = stack.pop();
if (knows(i, j))
stack.push(j);
else
stack.push(i);
}
}
Solution:
public class Solution extends Relation {
public int findCelebrity(int n) {
if (n <= 0)
throw new IllegalArgumentException("n is invalid");
if (n == 1)
return 0;
Stack<Integer> stack = new Stack<Integer> ();
for (int i = 0; i < n; i++)
stack.push(i);
while (stack.size() > 1) {
int i = stack.pop();
int j = stack.pop();
if (knows(i, j))
stack.push(j);
else
stack.push(i);
}
int j = stack.pop();
for (int i = 0; i < n; i++) {
if (i != j) {
if (!knows(i, j) || knows(j, i))
return -1;
}
}
return j;
}
}
[LeetCode#277] Find the Celebrity的更多相关文章
- 名人问题 算法解析与Python 实现 O(n) 复杂度 (以Leetcode 277. Find the Celebrity为例)
1. 题目描述 Problem Description Leetcode 277. Find the Celebrity Suppose you are at a party with n peopl ...
- [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 ...
- 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 ...
- [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 ...
- [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 ...
- 【LeetCode】277. Find the Celebrity 解题报告 (C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 暴力 日期 题目地址:https://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 exi ...
- [LC] 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 ...
- LeetCode All in One 题目讲解汇总(持续更新中...)
终于将LeetCode的免费题刷完了,真是漫长的第一遍啊,估计很多题都忘的差不多了,这次开个题目汇总贴,并附上每道题目的解题连接,方便之后查阅吧~ 477 Total Hamming Distance ...
随机推荐
- Win10 10586 更新
最近发现,电脑c盘突然少了许多,发现c盘多了个windowsBT文件夹,大概6个G,恩,win10 又推出更新了,版本10586. 不知道为啥,更新时win10 把原来的下载的删除了,大概出了什么错误 ...
- 遇到autoreconf: not found
sudo apt-get install autoconf automake libtool
- 使用Visual Studio发布应用安装包
安装包制作方式 使用Visual Studio进行应用的打包分发有两种方式: 1.使用Clickonce发布安装包: 2.使用Setup工程发布安装包. 操作步骤 Clickonce发布安装包 1.右 ...
- iOS8 【xcode6中添加pch全局引用文件】
前沿:xcode6中去掉了pch,为了一些琐碎的头文件引用,加快了 编译速度! xcode6之前的版本建项目就自动添加了是这样的: xcode6后的版本要自己手动的添加步骤如下: 1) 2) 3) ...
- 解压版tomcat设置为系统服务
1.先关闭tomcat,在"开始 "→"运行 "中输入cmd 命令,进入MS-DOS界面 2.进入 到tomcat的bin目录下 (解压版tomcat存放目录, ...
- 2014年12月23日00:42:54——PS4
http://tieba.baidu.com/p/3415598015?see_lz=1&pn=1 http://tieba.baidu.com/p/3188981817 http://tie ...
- 代码方式删除SVN
public static void delect(File s) { File b[] = null; if (s.exists()) {// 判读是否存在 if (s.isDirectory()) ...
- Java内存模型JMM与可见性
Java内存模型JMM与可见性 标签(空格分隔): java 1 何为JMM JMM:通俗地讲,就是描述Java中各种变量(线程共享变量)的访问规则,以及在JVM中将变量存储到内存和从内存中读取变量这 ...
- MySQL的基本使用
SQL DDL:数据定义语言 CREATE DROP ALTER DML:数据操作语言 SELECT INSERT UPDATE DELETE DCL:数据控制语言 GR ...
- Javascript执行环境、作用域链
执行环境 可以把执行环境想象为一个圆圈,里面包含了一些变量.函数. 执行环境定义了变量或函数的有权访问的其他数据,决定了它们各自的行为.还有一个顶部执行环境.在浏览器中,顶部执行环境既为window, ...