【问题标题】:Binary Arrays: Determine if all 1s in one array come before first 1 in the other二进制数组:确定一个数组中的所有 1 是否在另一个数组中的第一个 1 之前
【发布时间】:2018-05-04 13:05:48
【问题描述】:

我一直在研究一个有趣的问题,并认为我应该在这里发布它。问题如下:

给定两个数组,A 和 B,每个数组的元素是 0 或 1。目标是确定 A 中的所有 1 是否都在 B 中的第一个 1 之前。你可以假设所有 1 都是连续的 - 你不能在 2 个之间有 0。 (即你永远不会有 [1,0,1])。 一些例子:

正确:A = [0,1,1,0],B = [0,0,0,1]

正确:A = [1,0,0,0],B = [0,1,1,0]

错误:A = [0,0,0,1],B = [1,0,0,0]

错误:A = [0,1,1,0],B = [0,0,1,0]

您可以假设 len(A) = len(B) = N,但 N 可以非常大。因此,不能简单地将整个数组转换为二进制数,因为它太大而无法表示。

我想以最有效的方式找到解决方案,最好是 O(1)。我一直在使用 Numpy 数组在 Python 中对此进行编码,因此您可以对数组执行逻辑操作(例如 A 和 B,它会告诉您 A 和 B 之间是否有任何 1 重叠)。很想看看您能想出的任何解决方案!

【问题讨论】:

  • 直接的解决方案是找到 B 中第一个出现的 1 的索引,然后检查 A 中的所有 1 是否都有较小的索引。我看不出你怎么可能在不到 O(N) 的时间内做到这一点,因为你必须检查 A 的所有元素。
  • 我在想有一种方法可以在这里巧妙地使用位算术。例如,如果 A&B 全部为 0,则没有重叠,那么您只需检查 A > B
  • 虽然按位运算非常快,但它们仍然是O(#bits) = sizeof(type)*8*N,即O(N)

标签: python algorithm numpy bit-manipulation time-complexity


【解决方案1】:

如果您查看this question,您可以找到如何获取 numpy 数组中最后一个“最大值”值的索引。然后检查它是否小于 B 中的第一个 1 并且你很好。

import numpy as np
reverse_A = A[::-1]
i = len(reverse_A) - np.argmax(reverse_A) - 1
i < np.argmax(B)

【讨论】:

  • 是的,但是复杂度不能小于 O(n),因为您必须检查第一个 1B 中的位置。如果这是 B 的最后一个元素,你必须遍历所有元素才能找到它,这意味着至少有一个循环,这意味着 O(n)。
【解决方案2】:

如果数组的元素很少,您可以使用位算术来确定这一点。我不认为你能比这更快。这是节点中的一个小测试:

> test = (a,b) => a > b && (a&b === 0);
[Function: test]
> test(0b0110, 0b0001)
true
> test(0b1000, 0b0110)
true
> test(0b0001, 0b1000)
false
> test(0b0110, 0b0010)
false

和常规方法。优化在于您可以在 b 中的第一个 1 到达时或在 a 中的所有 1 都通过之后立即停止循环。

const test = (a, b) => {
  let state = 0;
  for (let i=0; i<a.length; i++) {
    if (a[i] === 1) state = 1;
    else if (state === 1) {
      state = 2;
      return b[i] === 0;
    }

    if (b[i] === 1) {
      return state === 2;
    }
  }
}

【讨论】:

  • 问题是数组可以有很多元素。认为 N > 500
  • @tgordon18 制作了数组的方法。
  • 虽然这仍然是 O(n) :(
  • @tgordon18 正如 Tony Tannous 对这个问题的评论,要么使用位操作并限制大小 O(1),要么你至少需要做一个 for ,那就是 O(n)。
  • 如果您知道 N=500,您能否使用位运算在数组上实现 A > B 并使其 O(1)?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-06-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-20
  • 2014-11-01
  • 1970-01-01
  • 2020-03-18
相关资源
最近更新 更多