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
人。在每次迭代中,我们从列表中删除一个人。我们 利用以下关键观察:如果person
1
知道person
2
, 那么这个人
1
就不是名人了;如果人员
1
不认识人员
2
, 那么这个人就不是名人了。因此,通过询问person
1
是否知道 person
2
,我们可以从列表中删除person
1
或person
2
可能的名人。我们可以反复使用这个想法来消除 除了一个人以外的所有人都说person
p
。我们现在用蛮力进行验证
p
是否是名人:对于每一个人
i
,我们都会问这个人
p
他是否认识那个人,我们问他是否知道 个人
p
。如果person
p
总是回答no,而其他人总是回答no 回答是,我们宣布此人
p
为名人。否则,我们 得出结论,在这个群体中没有名人

  • 把所有的人分成两人一组

  • 对于每一对(A,B),询问A是否知道B

    • 如果答案是肯定的,A不可能是名人,抛弃他
    • 如果答案是否定的,B不能成为名人,抛弃他
    现在,只有一半的人还活着

  • 从1开始重复,直到只剩下一个人

  • 成本O(N)。

    这里是O(N)时间算法

  • 将所有元素推入堆栈
  • 去掉最上面的两个元素(比如A和B),如果B知道A,而A不知道B,则保留A
  • 删除两个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;
    }