Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.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_Sorting_Math - Fatal编程技术网

Algorithm 查询数组中数字的范围

Algorithm 查询数组中数字的范围,algorithm,sorting,math,Algorithm,Sorting,Math,给定N个输入整数和M个查询范围,输出属于每个查询范围的整数集(两个边界都包含在内)。例如: N = [-10, -1, -2, 0, 0, 8, 12, 16] M = [(-100, 0), (2, 5), (13, 18)] 答案/输出将是: [-10, -1, -2, 0, 0] [] [16] 我一直在试图找到最佳的解决方案,并且正在努力想出一些在最坏的情况下比O(N*M)更好的方法。到目前为止,我考虑的方法有: 暴力-对于每个查询,检查N中的每个数字,看看它是否在范围内 预分类输入

给定N个输入整数和M个查询范围,输出属于每个查询范围的整数集(两个边界都包含在内)。例如:

N = [-10, -1, -2, 0, 0, 8, 12, 16]
M = [(-100, 0), (2, 5), (13, 18)]
答案/输出将是:

[-10, -1, -2, 0, 0]
[]
[16]
我一直在试图找到最佳的解决方案,并且正在努力想出一些在最坏的情况下比O(N*M)更好的方法。到目前为止,我考虑的方法有:

暴力-对于每个查询,检查N中的每个数字,看看它是否在范围内

预分类输入-对输入数字进行排序(O(NlogN)),然后执行上述操作。可以对完全超出范围的查询进行边界检查,并消除迭代的需要(例如,对[5,6,7]之类的列表进行查询(0,2))。这仍然需要迭代,在最坏的情况下仍然是O(NM)(对吗?)

哈希集-将输入数组中的每个值添加到哈希集中,然后针对查询范围内的每个可能整数值,检查哈希集中是否存在该整数值。这适用于较小的范围,但基本上是相同的->它是O(MX),其中X是查询范围的长度。因此,如果您的查询范围很大(即(-10000000,10000000)),它将无法扩展

我希望听到/了解更好的解决方案!(这个问题的另一个选择是确定每个查询范围内的数字,而不是输出数字)


请让我知道

我建议对范围进行排序,而不是对输入数字进行排序,然后简单地检查是否有任何给定的输入与某个范围匹配得更好,如果您可以在数字列表之前获得范围,那么您只能对数字进行一次迭代(当您读取它们时)

您仍然需要迭代输入数字列表(在这方面没有任何帮助),但是范围列表应该比数字列表小,因此排序和搜索都会更快。

可以在
(2*M+N)log(2*M+N)
中使用扫描线算法完成

创建事件列表:

  • 来自N的数字
  • 间隔从M开始
  • 从M开始的间隔结束
按位置对它们进行排序(在平局的情况下,您必须根据事件进行排序:取决于您的范围是打开的还是关闭的)

然后迭代事件:

  • 如果是开始间隔,则将其添加到当前打开的间隔中
  • 如果是结束间隔,则将其从当前打开的间隔中删除
  • 如果是N中的数字,则将其添加到所有打开的间隔中
因此,在您的情况下,事件列表将是

{-100S -10N -2N -1N, 0N, 0N, 0E, 2S, 5E, 8N, 12N, 13S, 16N, 18E}
  • -100S:修改活动间隔
    [(-100,0)]
  • -10N,-2N,-1N,0N,0N:将其添加到
    [(-100,0)]
  • -0E:活动间隔:
    []
  • 2S:有效间隔:
    [(2,5)]
  • 5E:活动间隔:
    []
  • 8N、12N:将其添加到无间隔
  • 13S:有效间隔:
    [(13,18)]
  • 16N:将其添加到间隔
    (13,18)
  • 18E:活动间隔:
    []
有关:


恐怕这更像是一个讨论问题,而不是堆栈溢出问题。不确定这在堆栈交换中的哪个位置更合适。查询范围会重叠吗?@user4581301是的,我也很害怕,我只是不知道该问哪里this@Jarod42是的,他们可以!好的,更复杂,但在
(N+M)log(N+M)
中应该是可行的。这是有道理的,对范围进行排序可能会导致速度优化。这仍然是O(N*M)最坏的情况,对吗?这太神奇了,我从来没有听说过扫描线算法。最后一件事,是否可以解释为什么它是O(M+N(log(M+N)),我可以理解它来自排序(并且可以看到添加查询范围如何改变典型的排序运行时)。它是否简单到:既然列表现在是M+N,排序需要(M+N)log(M+N)时间?
(2*M+N)log(2*M+N)
来自对所有事件的排序,有
2M+N
事件。太好了-这很有意义。谢谢!