Algorithm 在2^n时间算法问题中查找n*2^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)内存。虽然我不确定它是否足够。如果你知道一个使用任意内存量的答案,那就好了) 输入示例: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)内存。虽然我不确定它是否足够。如果你知道一个使用任
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==001O(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