Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 整数数组中范围相等的高效查询_Algorithm_Performance_Time - Fatal编程技术网

Algorithm 整数数组中范围相等的高效查询

Algorithm 整数数组中范围相等的高效查询,algorithm,performance,time,Algorithm,Performance,Time,给定一个大小为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.然后逐元素比较并返回true或falseO(n) 因此,解决方案的复杂性是O(

给定一个大小为
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.然后逐元素比较并返回
true
false
<代码>O(n)

因此,解决方案的复杂性是
O(q*n*logn)
,其中
q
是查询的数量。有可能有效地解决这个问题吗


PS:所有变量
n
q
和数组元素的约束都是
尽管也可能有其他方法来解决这个问题,但下面的方法可以很好地解决O(n)中的问题。(如果查询出现的次数为x,则O(xN)也可以通过缓存查询结果来优化,仅缓存查询范围及其结果)

为了方便起见,让我们将查询中的开始和结束元素命名为
range1StartIndex
range2StartIndex
Range1Index
Range2Index

  • 查看两个范围的结束和开始元素之间的差异是否不相等,当然,然后返回“否”,否则进入下一步
  • (如果两个范围的差异相等,则需要处理数组元素)

  • 初始化HashMap,将其命名为
    countMap
    。从
    range1StartIndex
    迭代数组,直到
    range1EndIndex
    并将遇到的每个字符及其发生总数作为条目放入映射中。进入下一步

  • range2StartIndex
    迭代数组,直到
    range2EndIndex
    。当遇到字符时,请查看它是否出现在
    countMap
    中。如果不存在或计数为0,则返回“否”。如果存在,则将计数减少一,然后进入下一步

  • 迭代
    countMap
    的键,如果任何键的计数大于1,则返回“否”,否则进入下一步

  • 返回“是”。退出


  • 好的,让我们从数组开始:
    125512

    这个数组有四个不同的元素(我们称这个数字为
    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'[1]: 0 5
    D'[2]: 1 6
    D'[3]: 3
    D'[5]: 2 4
    
    它们包含到那时为止遇到的每个不同元素的数量。此列表的大小显然是
    d*n

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

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

    我还省略了一些相当简单的优化,比如如果两个区间长度不相等,或者如果发现任何差异都不同,就提前退出


    更新:

    您也可以按如下方式存储相同的地图:

    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'[1]: 0 5
    D'[2]: 1 6
    D'[3]: 3
    D'[5]: 2 4
    
    此地图仅包含原始
    D[]
    将更改的位置的索引。此映射的大小始终为
    n
    ,但是计算
    D[E][y]-D[E][x]
    现在涉及到二进制搜索,它仍然保持
    O(n)
    最坏情况下的每个查询成本


    但它仍然不适合短范围的查询,在短范围内,对每个项目进行简单的比较会产生更好的结果。

    是否有空间限制?你总是可以用时间换取空间。@biziclop。。。您可以安全地占用高达50MB的空间。您的意思是
    O(q*N)
    。但在这种情况下,也可以看到整数的范围(
    您可以构建一个segemnt树,其中的节点表示范围并包含该范围内数字的哈希代码。只有在表示查询的节点包含的哈希代码相同的情况下,您才需要进行比较,否则您知道它们不相等。考虑到最坏的情况,内存复杂性为
    (10^5)^2
    ,这是
    10^10
    …远大于
    50MB
    我猜:)@yobro97是的,这特别适用于不同值的数量相当低但需要提供大量查询的情况。请注意,尽管
    d
    增加,存储
    d
    的每个值所需的位数会减少。事实上,如果所有元素都是唯一的,则只需存储每个元素的索引映射你能用一个例子来解释这个'D[E][y]-D[E][x])吗?