Algorithm 在2^n时间算法问题中查找n*2^n矩阵中缺少的行

Algorithm 在2^n时间算法问题中查找n*2^n矩阵中缺少的行,algorithm,matrix,powerset,Algorithm,Matrix,Powerset,我遇到了一个算法问题,起初看起来很简单,但我很困惑,不知道该怎么办!问题如下: 假设我们有一个数字n,然后我们有一个由n列和2*n行组成的矩阵。它类似于功率集(例如,对于n=2,我们有10,11,00,01)。行不一定遵循任何顺序。我们还可以在O(1)时间内访问每个矩阵成员。现在,我们有(2^n)-1行,我们希望在尽可能短的时间内找到最后一行(注意,有n*(2^n-1)个成员,我们只有O(2^n)个时间)。我们怎样才能做到这一点?(我们有O(n)内存。虽然我不确定它是否足够。如果你知道一个使用任

我遇到了一个算法问题,起初看起来很简单,但我很困惑,不知道该怎么办!问题如下:

假设我们有一个数字n,然后我们有一个由n列和2*n行组成的矩阵。它类似于功率集(例如,对于n=2,我们有10,11,00,01)。行不一定遵循任何顺序。我们还可以在O(1)时间内访问每个矩阵成员。现在,我们有(2^n)-1行,我们希望在尽可能短的时间内找到最后一行(注意,有n*(2^n-1)个成员,我们只有O(2^n)个时间)。我们怎样才能做到这一点?(我们有O(n)内存。虽然我不确定它是否足够。如果你知道一个使用任意内存量的答案,那就好了)

输入示例:

3
101
110
100
000
111
011
010
输出示例:
001

我试图通过流行的缺失位问题(通过对矩阵成员进行异或运算)对其进行建模,但进展不大

另外,在C/C++/Java/Python上实现该算法将非常有价值,因为它可以澄清问题


附言:你也能举出一些来源吗?或者告诉我你是如何得出答案的,以及你是如何看待这些问题的?

约束条件有点模糊,但你可能在寻找类似的东西:

  • 检查所有2^n行中的第一项,以确定缺少行中的第一项。1或零将开始2^(n-1)行,另一个选项将开始2^(n-1)-1行——计数较低的项将开始缺少的行
  • 检查2^(n-1)-1行中以与缺失行相同的项目开头的第二个项目,以查找缺失行中的第二个项目
  • 继续查找丢失行中的所有n项

如果将读取的元素数相加,则得到2^n+2^(n-1)+2^(n-2)。。。小于2^(n+1),因此在O(2^n)

中有
2
情况:

  • 退化情况:
    N==1
    ,这很明显<代码>0->1和
    1->0
    ;比如说,你可以把它放在
    ~item

  • 一般情况
    N>1
    。您所要做的就是对所有值进行异或操作:

    101^110^100^000^111^011^010==001

  • 该算法具有
    O(N*2**N)
    时间复杂度(我们必须读取矩阵的每个单元),并且需要
    O(N)
    空间(在xoring时存储时间和)

    C#实现(Linq):

    让我们来证明算法的正确性(
    N>1

    由于
    N>1
    因此
    2**N>=4
    那么
    2**(N-1)
    是一些偶数。让我们看看power系列中所有
    2**N
    项的任意位

     000...0...0
     000...0...1
      ...
     111.......0
     111...1...1
           ^
         - N/2 '0's (even) and N/2 '1' (even), xor == 0
    
    我们发现正好有
    N/2
    0和
    N/2
    1<所有这些位的strong>xor总是
    0
    (因为
    N/2==2**(N-1)
    是一些偶数值)。 如果遗漏一行,例如,
    0…1…1
    我们有
    2
    的可能性:

  • 丢失的位为
    1
    。所以我们有
    N/2
    0和
    N/2-1
    1<所有位的strong>xor返回
    1
  • 丢失的位为
    0
    。所以我们有
    N/2-1
    0和
    N/2-1
    1<所有位的strong>xor返回
    1

  • 因为
    ^
    是按位操作(第位
    j
    的值不取决于第位
    i
    的值)我们证明了任意位是正确的,整个值也是正确的。

    输入和输出的示例更好。示例I/O ADDEX或所有值:
    101^110^100^000^111^011^010==001
    谢谢您的回答,但是对于第二行,我们如何标记前面的2^(n-1)行?这样我们就可以返回到第二行和第三行,依此类推?最简单的方法是保留一个相关行的列表,在每个步骤中过滤掉不相关的行。这需要O(2^n)空间。或者,如果矩阵表示法允许您在固定时间内执行此操作,则可以将相关行交换到顶部。这需要恒定的额外空间。xoring所有值与O(n*2^n)时间有关,因为矩阵中有多少个单元格。
     000...0...0
     000...0...1
      ...
     111.......0
     111...1...1
           ^
         - N/2 '0's (even) and N/2 '1' (even), xor == 0