【问题标题】:Equal elements in SubArraySubArray 中的相等元素
【发布时间】:2015-05-14 19:27:10
【问题描述】:
我有一个包含 N 个元素的数组,我需要找到子数组中 相等的索引 元素之间的距离;我们将以查询(L R)的形式得到,其中 L 是子数组的起始索引,R 是结束索引。
数组元素的总数可以是 N 和查询 Q。
例如:
7
0 4 0 8 0 32 0
2
0 2
0 5
//第一个查询的答案将是 2(索引 2-0)
//第二个查询的答案将是 8 (index (2-0) + (4-2) + (4-0))
编辑:我不指望代码(尽管它真的很有帮助)解决的一般想法会很有帮助。
【问题讨论】:
标签:
python
c++
algorithm
data-structures
bit-manipulation
【解决方案1】:
这是一个用于 sqrt 分解的工作。
我们希望保持状态,使我们能够回答当前范围并向上或向下调整当前范围的端点。为此,我们维护一个从元素到的映射(当前范围内该元素的所有索引的总和,当前范围内的出现次数)。我们也维持当前的答案。为了向下调整下端点以包含索引 i 处的元素 x,我们通过范围内的索引总和来增加答案 - (#occurrences of x in range * i),然后增加总和和出现的次数。其他三个操作类似。
为了实现sqrt分解,我们按照(下端点地板除以sqrt N,上端点)对查询进行排序,并按顺序调整范围。
【解决方案2】:
创建一个映射,其键是数组的元素,值是它们出现的位置列表(您的示例将变为{0: [0, 2, 4, 6], 8: [3], 4: [1], 32: [5]})。这些群体形成不相关的问题。找到答案的一种方法是将它们视为maximum flow problems,其中每个索引形成两个顶点。
每个索引都连接到它后面的所有索引,并且它前面的所有索引都连接到它。边的权重是数组中元素的距离,即两个索引之间的差异。所有“源”顶点都连接到无限源,所有“目标”顶点都连接到接收器。
所有问题的最大流量值的总和就是您要查找的总和。
例如,让我们使用项目0 的索引:
+-------- 0 ----------+ 0 --------+
| | |
| | |
Source ----+-------- 2 -------+ +----> 2 --------+---- Sink
| | | |
| | | |
+-------- 4 ----+ +--+----> 4 --------+
| | | | |
| | | | |
+-------- 6 +--+--+----> 6 --------+
Weight of arc (u, v) = v - u
请注意,边的数量会随着 V^2 的增长而增长,因为每条边都对应于计算结果所需的差异,这些差异位于每个索引与其所有后继索引之间。这使得解决方案的复杂度为 O(n^3),甚至比朴素算法还要糟糕,这只是从另一个角度看待事物的好方法:)