给定一个大小为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)
的数组的两个副本
然后对每一个进行排序。 O(n*logn)
3.然后逐个元素比较并返回true
或false
。 O(n)
因此,解决方案的复杂性为O(q*n*logn)
,其中q
是查询的数量。是否有可能有效地解决这个问题?
PS:所有变量n
,q
和数组元素的约束为<=10^5
。
答案 0 :(得分:1)
虽然也可能有其他方法来解决这个问题,但是下面的方法可以很好地解决这个问题,在O(N)中。 (如果查询到达的次数为x次,则可以通过缓存查询结果来优化O(xN),只查询查询范围及其结果)
为了便于我们,请将查询中的起始和结束元素命名为
range1StartIndex
,range2StartIndex
,range1EndIndex
和range2EndIndex
。
(如果两个范围的差异相等,那么我们需要处理数组元素。)
初始化HashMap,让它命名为countMap
。将数组从range1StartIndex
迭代到range1EndIndex
并将映射作为每个遇到的字符的条目及其出现的总数。转到下一步。
将数组从range2StartIndex
迭代到range2EndIndex
。遇到一个字符,看它是否存在于countMap
中。如果它不存在或其计数为0则返回&#34;否&#34;。如果存在,则将计数减1,然后转到下一步。
迭代countMap
的键,如果任何键的计数大于1,则返回&#34;否&#34;,否则转到下一步。
返回&#34;是&#34;。出口。
答案 1 :(得分:0)
好的,让我们从数组开始: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
。
完成后,对于每个查询,您只需通过计算E
来检查(x,y)
范围内每个不同元素D[E][y]-D[E][x])
的数量。两个范围将包含完全相同的元素iff对于所有不同的元素,这个差异是相同的。
显然,如果与n
相比,不同元素的数量相对较低,则此解决方案效果最佳,每个查询成本为O(distinct values)
。
我也省略了一些相当简单的优化,比如如果这两个范围长度相等,或者如果发现任何差异不同,则提前退出。 < / p>
<强>更新强>
您还可以像这样存储相同的地图:
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)
最差情况。
但它仍然不适合短距离查询,每个项目的天真比较会产生更好的结果。