【问题标题】:Efficient querying for equality of ranges in an integer array有效查询整数数组中范围的相等性
【发布时间】:2017-11-06 16:45:00
【问题描述】:

给定一个大小为n 的正整数数组,它期望找出两个范围是否在查询相等时给出。如果范围 1 中存在的所有元素都存在于范围 2 中并且计数相同,则认为两个范围相等。

例子:

1 2 5 3 5 1 2

查询:

[1,3] and [5,7]
[2,4] and [3,5]

答案:

Yes
No

可以通过以下方式提出一个简单的解决方案:
1. 对于每个查询,制作存储每个范围 O(n) 的数组的两个副本。
2. 然后对它们中的每一个进行排序。 O(n*logn)
3. 然后逐个元素比较,返回truefalseO(n)

所以解决方案的复杂度是O(q*n*logn),其中q 是查询的数量。是否有可能有效地解决这个问题?

PS:所有变量nq和数组元素的约束为<=10^5

【问题讨论】:

  • 有空间限制吗?您总是可以用时间换取空间。
  • @biziclop ...您可以安全地占用50MB 的空间。

标签: algorithm performance time


【解决方案1】:

虽然可能还有其他方法可以解决这个问题,但下面的方法可以很好地在 O(N) 中解决这个问题。 (如果查询出现 x 次,则 O(xN) 可以通过缓存查询结果来优化,只是查询范围及其结果)

为了方便起见,我们将查询中的开始和结束元素命名为 range1StartIndexrange2StartIndexrange1EndIndexrange2EndIndex

  1. 查看两个范围的结束元素和开始元素之间的差异是否不相等,则返回“否”,否则进入下一步。

(如果两个范围的差值相等,那么我们需要处理数组元素)。

  1. 初始化一个HashMap,我们把它命名为countMap。从range1StartIndexrange1EndIndex 迭代数组并放入map 作为遇到的每个字符的条目及其出现的总数。进入下一步。

  2. range2StartIndexrange2EndIndex 迭代数组。当遇到一个字符时,查看它是否存在于countMap 中。如果它不存在或它的计数为 0,则返回“No”。如果存在,则将计数减一并移至下一步。

  3. 迭代countMap的keys,如果任何key的count大于1,返回“No”,否则进入下一步。

  4. 返回“是”。出口。

【讨论】:

  • 你的意思是O(q*N)。但是在这种情况下,也看到可能的整数范围(<=10^5),有一个logn 因子而不是为每个查询遍历整个哈希表不是更好吗? (点号4)。
  • 您可以构建一个分段树,其节点表示范围并包含该范围内数字的哈希码。仅当代表查询的节点包含的 tge 哈希码相同时才需要进行比较,否则您知道它们不相等。
【解决方案2】:

好的,让我们从数组开始:1 2 5 3 5 1 2

这个数组有四个不同的元素(我们称这个数字为d),我们可以像这样预先计算四个列表:

D[1]: 1 1 1 1 1 2 2
D[2]: 0 1 1 1 1 1 2
D[3]: 0 0 0 1 1 1 1
D[5]: 0 0 1 1 2 2 2

这些包含到该点为止遇到的每个不同元素的数量。这个列表的大小显然是d*n

完成后,对于每个查询,您可以通过计算 D[E][y]-D[E][x]) 来简单地检查 (x,y) 范围内每个不同元素 E 的数量。如果所有不同元素的差异相同,则两个范围将包含完全相同的元素。

显然,如果与n 相比,不同元素的数量相对较少,则此解决方案效果最佳,每次查询的成本为O(distinct values)

我还省略了一些相当简单的优化,例如如果两个范围的长度不相等,或者如果发现任何差异不同,则提前退出。


更新:

您也可以像这样存储相同的地图:

D'[1]: 0 5
D'[2]: 1 6
D'[3]: 3
D'[5]: 2 4

此地图仅包含原始 D[] 将更改的位置的索引。此映射的大小始终为n,但计算D[E][y] - D[E][x] 现在涉及二分查找,它仍然保持O(n) 最坏情况下的每次查询成本。

但它仍然不适合短距离查询,其中每个项目的幼稚比较会产生更好的结果。

【讨论】:

  • 考虑到最坏的情况,内存复杂度是(10^5)^2,它是10^10......远大于50MB 我猜:)。
  • @yobro97 是的,这专门用于不同值的数量相当少但您必须处理大量查询的情况。请注意,随着d 的增加,存储D 的每个值所需的位数会减少。事实上,如果所有元素都是唯一的,你只需要存储每个元素的索引的映射。
  • @biziclop 你能用一个例子解释一下这个'D[E][y]-D[E][x])'吗?
猜你喜欢
  • 2020-02-02
  • 1970-01-01
  • 1970-01-01
  • 2022-08-09
  • 1970-01-01
  • 2013-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多