一尘不染

在数组中查找连续范围

algorithm

您将得到一个整数数组。您必须输出最大范围,以便该范围内的所有数字都出现在数组中。数字可能以任何顺序出现。例如,假设数组为

{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 []数组。


阅读 258

收藏
2020-07-28

共1个答案

一尘不染

我认为以下解决方案将在O(n)时间中使用O(n)空间工作。

首先将数组中的所有条目放入哈希表。接下来,创建第二个哈希表,该表存储我们已“访问”的元素,该元素最初为空。

现在,一次遍历元素数组。对于每个元素,检查该元素是否在访问集中。如果是这样,请跳过它。否则,从该元素开始向上计数。在每个步骤中,检查当前数字是否在主哈希表中。如果是这样,请继续,并将当前值标记为已访问集的一部分。如果没有,请停止。接下来,重复此过程,除了向下计数。这告诉我们包含此特定数组值的范围内的连续元素数。如果我们跟踪以这种方式找到的最大范围,我们将有一个解决方案。

该算法的运行时复杂度为O(n)。要看到这一点,请注意,我们可以在O(n)时间的第一步中构建哈希表。接下来,当我们开始扫描到数组以找到最大范围时,每个扫描范围所花费的时间与该范围的长度成比例。由于范围长度的总和是原始数组中元素的数量,并且由于我们从未两次扫描相同的范围(因为我们标记了我们访问的每个数字),因此第二步将O(n)时间作为好,对于O(n)的净运行时间。

编辑: 如果您很好奇,我可以使用该算法的
Java实现
,以及对其工作原理以及运行时正确性的详细分析。它还探讨了一些在算法的初始描述中不明显的边缘情况(例如,如何处理整数溢出)。

希望这可以帮助!

2020-07-28