在线性时间内解决熟人任务

时间:2014-05-14 08:43:11

标签: algorithm complexity-theory time-complexity

鉴于n人的一组,A人可能知道或不知道B(也知道B知道B并不意味着B知道A)。由布尔运算的nxn矩阵定义的所有熟人 让我们将名人定义为人,每个人都知道,但谁也不认识。

任务是建议一种算法,该算法需要O(n)时间和O(1)额外空间来查找集合中的名人,或者声明该集合不包含任何名称。

首先,我的印象是,写这篇文章的人有意与那些将会解决这个问题的人的头脑混在一起。

我认为,这里的线性时间意味着我们可以比输入尺寸(实际上是n * n)花费时间线性。
然后提出二次时间算法似乎是微不足道的任务。另一方面,如果我们认为我误解了我先前的陈述,我不相信它可以在未分类矩阵中找到很多,其中k方为时间O(k)。 。

我将在此处留下二次时间算法的草稿:

for x in range(0,side-1):
    knowingAmount = sumAlongColumn(x)
    if knowingAmount == side:
        celebritySuspectKnows = sumAlongRow(x)
        if celebritySuspectKnows == 1:
            return x
return -1

所以,如果你们帮助我,我会很感激。我是否正确地解释了这个具有时间复杂性要求的警告,或者这里存在更有效的算法?

2 个答案:

答案 0 :(得分:3)

每个人:

  • 如果我们没有潜在的名人,请让这个人成为潜在的名人。

  • 如果潜在的名人和这个人都不认识对方,或者他们彼此认识,重置潜在的名人。

  • 如果潜在的名人知道这个人,而不是相反,让这个人成为新的潜在名人。


或者,简化:

让第一个人成为潜在的名人。

对于每个人:(从第二个开始)

  • 如果潜在的名人知道这个人,就让这个人成为新的潜在名人。

一旦完成,如果我们有一个潜在的名人,请再次检查,看看这个人是否认识其他人并且每个人都知道他们确保他们真的是名人。

复杂性: O(n)时间,O(1)空间。

证明正确性的关键是:

  • 如果这个人是名人,我们就无法继续前进,因为继续前进的唯一标准就是了解别人,这对名人来说是不可能的。

  • 如果一个人存在,我们将永远切换到名人,因为我们经历所有人并且如果一个人知道这个人总是切换,这对所有其他人来说都是真实的。

但是,如果没有名人,我们最后还会有一位(非名人)候选人(考虑到我们很容易提名某人作为潜在的名人),所以我们需要确保候选人是名人。

答案 1 :(得分:1)

能用消除的过程解决问题。

可以根据Knows[i][j]的值来消除其中一个人,其中i & j是名人。

  1. 我们不知道B,然后我们可以肯定地消除B,正如我们所知道的那样 每个人都知道名人。
  2. A知道B,然后我们消除A,因为名人不知道任何人。
  3. 现在我们可以将算法表示为

         Push All Celeb on Stack
    
        while stack is not empty{
         Pop Two Celeb i & j
    
         if(knows[i][j]) //i knows j
           push j //eliminate i
    
         else
           push i // i dosen't know j, so j is not celebrity.
    
        }
        C=(last element on stack)
    
       /* Now one person remains but we can't gurantee he is celebrity because we might have popped person who doesn’t know or some person he knows from the stack before we reach that celebrity */
    
    
       for( all celebrity except C){
            if(!knows[i][C]) return -1;
            if(knows[C][i]) return -1;
       }
       return C;