Algorithm “最佳解决方案”;“名人”;算法
在Algorithm “最佳解决方案”;“名人”;算法,algorithm,data-structures,time-complexity,complexity-theory,graph-algorithm,Algorithm,Data Structures,Time Complexity,Complexity Theory,Graph Algorithm,在n人中,“名人”被定义为某人 谁都认识,但谁都不认识。这个 问题是,如果名人存在,通过询问 问题只是形式上的“对不起,你认识那个人吗?” (假设所有答案都是正确的, 就连这位名人也会回答。) 目标是尽量减少问题的数量 有没有比这里明显的O(n^2)更少的顺序的解决方案?使用名人问题的分析 蛮力解。该图最多有n(n-1)边,我们可以通过询问每个潜在边来计算它。在这 点,我们可以通过计算顶点的 因度及其超度。此暴力解决方案要求n(n-1) 问题。接下来,我们将展示如何最多使用3(n-1) 问题和线
n
人中,“名人”被定义为某人
谁都认识,但谁都不认识。这个
问题是,如果名人存在,通过询问
问题只是形式上的“对不起,你认识那个人吗?”
(假设所有答案都是正确的,
就连这位名人也会回答。)
目标是尽量减少问题的数量
有没有比这里明显的
O(n^2)
更少的顺序的解决方案?使用名人问题的分析
蛮力解。该图最多有n(n-1)
边,我们可以通过询问每个潜在边来计算它。在这
点,我们可以通过计算顶点的
因度及其超度。此暴力解决方案要求n(n-1)
问题。接下来,我们将展示如何最多使用3(n-1)
问题和线性位置
一个优雅的解决方案。我们的算法由两个阶段组成:在淘汰阶段,除了一个人之外,我们将所有人都淘汰
名人;在验证阶段,我们会检查这个
剩下的人确实是名人。消除阶段
保留可能的名人名单。最初它包含所有n
人。在每次迭代中,我们从列表中删除一个人。我们
利用以下关键观察:如果person1
知道person2
,
那么这个人1
就不是名人了;如果人员1
不认识人员2
,
那么这个人就不是名人了。因此,通过询问person1
是否知道
person2
,我们可以从列表中删除person1
或person2
可能的名人。我们可以反复使用这个想法来消除
除了一个人以外的所有人都说personp
。我们现在用蛮力进行验证
p
是否是名人:对于每一个人i
,我们都会问这个人p
他是否认识那个人,我们问他是否知道
个人p
。如果personp
总是回答no,而其他人总是回答no
回答是,我们宣布此人p
为名人。否则,我们
得出结论,在这个群体中没有名人
- 如果答案是肯定的,A不可能是名人,抛弃他
- 如果答案是否定的,B不能成为名人,抛弃他
#include<iostream>
using namespace std;
int main(){
int n;
//number of celebrities
cin>>n;
int a[n][n];
for(int i = 0;i < n;i++){
for(int j = 0;j < n;j++){
cin>>a[i][j];
}
}
int count = 0;
for(int i = 0;i < n;i++){
int pos = 0;
for(int j = 0;j < n;j++){
if(a[i][j] == 0){
count = count + 1;
}
else{
count = 0;
break;
}
}
if(count == n){
pos = i;
cout<<pos;
break;
}
}
return 0;
}
#包括
使用名称空间std;
int main(){
int n;
//名人人数
cin>>n;
INTA[n][n];
对于(int i=0;i>a[i][j];
}
}
整数计数=0;
对于(int i=0;i
问题-名人是指其他人都知道但不认识的人。给定N个人(索引为0…(N-1)),并定义一个函数
如下所示:knowsOf(int person0,int person1)=如果人0认识人1,则为true,否则为false
找出N个给定人物中的名人(如果有的话)
//如果没有名人,返回-1,否则返回人物索引/编号
public int celeb(int n) {
int probaleCeleb = 0;
for(int i =1 ; i < n; i++) {
if(knowsOf(probaleCeleb , i)) { // true /false
probaleCeleb = i;
}
}
for(int i =0 ; i < n; i++) {
if( i != probaleCeleb &&
(!knowsOf( i , probaleCeleb) || (knowsOf( probaleCeleb , i)) ) {
probaleCeleb = -1;
break;
}
}
return probaleCeleb;
}
}
public int-celeb(int-n){
int probaleCeleb=0;
对于(int i=1;i
公共类解决方案{
公共int FindElebrity(int n){
如果(n这个问题可以在O(n^2)时间复杂度中使用图(indegree和outdegree概念)来解决。
我们还可以使用一个简单的双指针概念在O(N)时间和O(1)空间中解决这个问题。
我们将一次比较两个人,一个从开始,另一个从结束,我们将从考虑中删除那个不能成为名人的人。例如,如果有两个人X和Y,X可以识别人Y,那么X肯定不能成为名人,因为它知道党内有人。另一种情况是当X does不认识Y,在这种情况下,Y不可能是名人,因为在一个聚会中至少有一个人不认识他/她。使用这种直觉,可以应用双指针概念来查找聚会中的名人
我在Youtube上找到了algods制作的一段很好的解释视频
您可以参考此视频以获得更好的解释
视频链接:
int findCelebrity(int n){
int i=0;
对于(int j=1;jDoes),这有助于我投票结束这个问题,因为在它当前的形式下,它不是一个编程问题。除非你要进行任何假设或任何概率导数,否则我认为你已经提供了足够的约束,使解为n^2
public class Solution {
public int findCelebrity(int n) {
if (n <= 1) {
return -1;
}
int left = 0;
int right = n - 1;
// First find the right candidate known by everyone, but doesn't know anyone.
while (left < right) {
if (knows(left, right)) {
left++;
} else {
right--;
}
}
// Validate if the candidate knows none and everyone knows him.
int candidate = right;
for (int i = 0; i < n; i++) {
if (i != candidate && (!knows(i, candidate) || knows(candidate, i))) {
return -1;
}
}
return candidate;
}
}
int findCelebrity(int n) {
int i=0;
for(int j=1;j<n;j++){
if(knows(i,j)){
i=j;
}
}
for(int j=0;j<n;j++){
if(j!=i && (knows(i,j)|| !knows(j,i))){
return -1;
}
}
return i;
}