您将得到一个整数数组。您必须输出最大范围,以便该范围内的所有数字都出现在数组中。数字可能以任何顺序出现。例如,假设数组为
{2, 10, 3, 12, 5, 4, 11, 8, 7, 6, 15}
在这里,我们发现两个(非平凡的)范围,这些范围内的所有整数都存在于数组中,即[2,8]和[10,12]。这些[2,8]中较长的一个。所以我们需要输出。
当我被问到这个问题时,我被要求在线性时间内执行此操作,而不进行任何排序。我以为可能会有一个基于哈希的解决方案,但是我什么也没想出来。
这是我尝试的解决方案:
void printRange(int arr[]) { int n=sizeof(arr)/sizeof(int); int size=2; int tempans[2]; int answer[2];// the range is stored in another array for(int i =0;i<n;i++) { if(arr[0]<arr[1]) { answer[0]=arr[0]; answer[1]=arr[1]; } if(arr[1]<arr[0]) { answer[0]=arr[1]; answer[1]=arr[0]; } if(arr[i] < answer[1]) size += 1; else if(arr[i]>answer[1]) { initialize tempans to new range; size2=2; } else { initialize tempans to new range } } //I have to check when the count becomes equal to the diff of the range
我被困在这一部分…我不知道应该使用多少个tempanswer []数组。
我认为以下解决方案将在O(n)时间中使用O(n)空间工作。
首先将数组中的所有条目放入哈希表。接下来,创建第二个哈希表,该表存储我们已“访问”的元素,该元素最初为空。
现在,一次遍历元素数组。对于每个元素,检查该元素是否在访问集中。如果是这样,请跳过它。否则,从该元素开始向上计数。在每个步骤中,检查当前数字是否在主哈希表中。如果是这样,请继续,并将当前值标记为已访问集的一部分。如果没有,请停止。接下来,重复此过程,除了向下计数。这告诉我们包含此特定数组值的范围内的连续元素数。如果我们跟踪以这种方式找到的最大范围,我们将有一个解决方案。
该算法的运行时复杂度为O(n)。要看到这一点,请注意,我们可以在O(n)时间的第一步中构建哈希表。接下来,当我们开始扫描到数组以找到最大范围时,每个扫描范围所花费的时间与该范围的长度成比例。由于范围长度的总和是原始数组中元素的数量,并且由于我们从未两次扫描相同的范围(因为我们标记了我们访问的每个数字),因此第二步将O(n)时间作为好,对于O(n)的净运行时间。
编辑: 如果您很好奇,我可以使用该算法的 Java实现 ,以及对其工作原理以及运行时正确性的详细分析。它还探讨了一些在算法的初始描述中不明显的边缘情况(例如,如何处理整数溢出)。
希望这可以帮助!