处理大型数组时超时限制

时间:2014-11-11 05:39:08

标签: c++ arrays algorithm

我试图解决this question

  

众所周知,Varchas正在继续。所以FOC想要组织一个名为Finding Occurrence的活动。

     

任务很简单:

     

给定正整数的数组A [1 ... N]。会有Q查询。在查询中,您将获得一个整数。您需要找出给定数组中该整数的频率。

     

INPUT:

     

第一行输入包括整数N,即给定数组中的整数数。   下一行将包含N个空格分隔的整数。下一行将是Q,查询数量。   接下来的Q行将包含一个整数,你应该找出它。

     

输出:

     

为每个Query输出单个整数,它是给定整数的频率。

     

约束:

     

1·; = N< = 100000

     

1·; = Q< = 100000

     

0℃; = A [1] - ; = 1000000

这是我的代码:

#include <iostream>
using namespace std;

int main()
{
    long long n=0;
    cin >> n;
    long long a[1000000];
    for (int i=1;i<=n;i++)
    {
        cin >> a[i];
    }
    long long q=0;
    cin >> q;
    while (q--)
    {
        long long temp=0,counter=0;
        cin >> temp;
        for (int k=1;k<=n;k++)
        {
            if (a[k]==temp)
                counter++;
        }
        cout << "\n" << counter;
        temp=0;
        counter=0;
    }
    return 0;
}

但是,我遇到了超过时间限制&#39;错误。我怀疑这是由于无法处理数组中的大值。有人能告诉我如何处理如此大尺寸的阵列吗?

3 个答案:

答案 0 :(得分:4)

失败在算法本身,请注意,对于每个查询,您遍历整个数组。有100,000个查询和100,000个元素。这意味着在更糟糕的情况下,您将遍历100,000 * 100,000个元素= 10,000,000,000个元素,这些元素不会及时完成。如果您使用Big-O notation分析复杂性,那么您的算法为O(nq),这对于此问题来说太慢了,因为n*q很大。

你应该做的是在进行任何查询之前计算得分,然后存储在一个数组中(这就是为什么给出了A[i]的范围。你应该能够这样做通过遍历数组一次。(提示:您不需要将输入存储到数组中,您可以直接计算)。

通过这样做,算法将只是O(n),并且由于n足够小(根据经验,不到一百万是小的),它应该及时完成。< / p>

然后,您可以立即回答每个查询,使您的程序足够快,以便在时间限制之内。

您可以改进的另一件事是数组的数据类型。存储在该阵列中的值不会超过100万,因此您不需要使用更多内存的long long。您可以使用int

答案 1 :(得分:4)

您的算法效率低下。您将所有数字读入数组,然后通过数组线性搜索每个查询。

你应该做的是制作一系列计数。换句话说,如果您读取数字5,请执行count [5] ++。然后,对于每个查询,您只需从数组中返回计数。例如,阵列中有多少个5?答案:算[5]。

答案 2 :(得分:1)

由于您的最大数量可以是10 ^ 6,我认为您的问题将超出内存限制,即使它适合时间。另一种解决方案是对数组进行排序(您可以使用STL排序函数在N * logN中进行排序),对于每个查询,您可以进行两次二进制搜索。第一个用于查找元素出现的第一个位置,第二个用于查找元素出现的最后位置,因此每个查询的答案将是lastPosition - firstPosition + 1.