【问题标题】:Maximum OR value of 2D Array of bits二维位数组的最大 OR 值
【发布时间】:2017-12-28 13:56:26
【问题描述】:

假设有一个二维数组(m x n) 位。

例如:

1 0 0 1 0
1 0 1 0 0 
1 0 1 1 0
0 0 0 0 1

这里,m = 4n = 5

我可以翻转(0 变为 11 变为 0)任何行中的位。当您翻转特定行中的位时,您会翻转所有位。

我的目标是获得给定行对之间的最大 OR 值。

也就是说,如果给定的行对是(r1, r2),那么我可以在r1r2 之间翻转任意数量的行,并且我应该找到之间所有行的最大可能ORr1r2

在上面的例子中(考虑索引从 1 开始的数组),如果r1 = 1 和r2 = 4,我可以翻转第一行得到0 1 1 0 1。现在,如果我找到从 1 到 4 的所有行的 OR 值,我会得到 31 值作为最大可能的 OR 值(可以有其他解决方案)。

此外,最好计算 (r1, r1)(r1, r1+1)(r1, r1+2)、...、(r1, r2-1) 的答案,同时计算 (r1,r2) 的答案。

约束

1 <= m x n <= 10^6

1 <= r1 <= r2 <= m

一个简单的蛮力解决方案的时间复杂度为O(2^m)。 有没有更快的计算方法?

【问题讨论】:

  • 这个算法有什么应用?
  • 我不明白你是怎么得到 O(2^m) 的,如果你一点一点地执行操作,对行对的天真迭代宁愿是 O(m*n^2),或者 O(n^2) 如果 m
  • @aka.nice 因为有 m 行,我可以选择 nC0, nC1, nC2, nC3, ..., nCn 行来翻转。现在,nC0 + nC1 + nC2 + nC3 + ... + nCn = 2^n。
  • @NikunjMadhogaria 啊,现在我明白了,首先我反转了 m & n,其次,您可以 OR 任意数量的行,而不仅仅是一对行。

标签: algorithm multidimensional-array bit-manipulation dynamic-programming


【解决方案1】:

由于A <= A | B,数字A的价值只会随着我们OR更多的数字而上升。

因此,我们可以使用二分查找。

我们可以使用函数来获取两行之间的最大值并将ORed 结果保存为第三行。然后比较这第三行中的两个得到更高级别的行,然后再比较这两个更高级别的行,以此类推,直到只剩下一个。

使用您的示例:

array1 = 1 0 0 1 0 [0]
         1 0 1 0 0 [1]
         1 0 1 1 0 [2]
         0 0 0 0 1 [3]

array2 = 1 1 0 1 1 <-- [0] | ~[1]
         1 1 1 1 0 <-- [2] | ~[3]

array3 = 1 1 1 1 1 <-- [0] | [1]

显然,当m 不是 2 的幂时,您可以根据需要截断分支。

所以现在是O(m) 时间。请记住,对于大量行,可能没有唯一的解决方案。结果很可能是2 ^ n - 1

一个重要的优化:如果m &gt;= n,那么输出一定是2 ^ n - 1。假设我们有两个数字 A 和 B。如果 B 有 k 数字缺失位,那么 A~A 将保证至少填充其中一个位。类似地,如果m &gt;= log n,那么输出也必须是2 ^ n - 1,因为每个A~A 都保证填充B 中至少一半的未填充位。

使用这些快捷方式,您可以根据需要进行蛮力搜索。我不是 100% 二进制搜索算法适用于每种情况。

【讨论】:

  • 你如何决定~哪一行?
  • 只需检查所有四种组合。可能两者都需要~
  • 考虑 100 行,在这种情况下,矩阵的上半部分和下半部分将有 2^50 种组合。
  • 没有。第一层比较50对,第二层比较25对,第三层比较13对,依此类推。大约。总共 100 个。
  • 你的意思是我们只会成对比较?怎么能说nth行对(n+2)th行没有影响?
【解决方案2】:

考虑到翻转整个​​矩阵中的行然后将它们组合在一起以获得尽可能多的 1 的问题,我声称当列数小于 2^m 时这是易于处理的,其中 m 是行数。逐行考虑。在我从 0 开始计数的阶段,你有少于 2^(m-i) 个零要填充。因为翻转一行会将 0 变为 1,反之亦然,因此当前行或翻转的行将填充这些零的至少一半。当您完成所有行后,您将有少于 1 个零要填充,因此此过程可以保证提供完美的答案。

我声称当列数至少为 2^m 时,这是易于处理的,其中 m 是行数。有 2^m 种可能的翻转行模式,但这只是 O(N),其中 N 是列数。因此,在这种情况下,尝试所有可能的翻转行模式会给你一个 O(N^2) 算法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-06-28
    • 2016-06-21
    • 2016-04-14
    • 1970-01-01
    • 2017-03-16
    • 2017-02-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多