如何降低此代码的复杂性

时间:2013-10-02 14:33:03

标签: c++ algorithm

请任何人提供更好的算法,然后尝试解决此问题的所有组合。

  

给定N个数字的数组A,找到不同对的数量(i,   j)使得j> = i且A [i] = A [j]。

     

输入的第一行包含多个测试用例T.每个测试   case有两行,第一行是数字N,后面是一行   由N个整数组成,它们是数组A的元素。

     

对于每个测试用例,打印不同对的数量。

     

约束:   1< = T< = 10
  1< = N< = 10 ^ 6
  -10 ^ 6< = A [i]< = 10 ^ 6,0< = i< Ñ

我认为首先对数组进行排序,然后查找每个不同整数的频率,然后添加所有频率的nC2,最后添加字符串的长度。但不幸的是,它给出了一些不为人知的帮助的错误。这是实施。

code:
#include <iostream>
#include<cstdio>
#include<algorithm>
using namespace std;

long fun(long a) //to find the aC2 for given a
{
    if (a == 1) return 0;
    return (a * (a - 1)) / 2;
}

int main()
{
    long t, i, j, n, tmp = 0;
    long long count;
    long ar[1000000];
    cin >> t;

    while (t--)
    {
        cin >> n;
        for (i = 0; i < n; i++)
        {
            cin >> ar[i];
        }
        count = 0;
        sort(ar, ar + n);

        for (i = 0; i < n - 1; i++)
        {
            if (ar[i] == ar[i + 1])
            {
                tmp++;
            }
            else
            {
                count += fun(tmp + 1);
                tmp = 0;
            }
        }

        if (tmp != 0)
        {
            count += fun(tmp + 1);
        }
        cout << count + n << "\n";

    }
    return 0;
}

1 个答案:

答案 0 :(得分:2)

记住每个数字在数组中出现的次数。然后遍历结果数组并为每个数组添加triangular number

例如(来自源测试案例):

Input:
3
1 2 1

count array = {0, 2, 1} // no zeroes, two ones, one two
pairs = triangle(0) + triangle(2) + triangle(1)
pairs = 0 + 3 + 1
pairs = 4

三角数可以由(n * n + n) / 2计算,整个数据是O(n)。

编辑:

首先,如果您计算频率,则无需进行排序。我看到你对排序做了什么,但如果你只保留一个单独的频率阵列,那就更容易了。它需要更多空间,但由于元素和数组长度都被限制在< 10^6,因此您需要的最大值是int[10^6]。这很容易适应挑战中给出的256MB空间要求。 (哎呀,因为元素可以变为负数,你需要一个两倍大小的数组。但仍然在极限之下)

对于n choose 2部分,您错误的部分是n+1 choose 2问题。由于您可以自己配对每个,因此您必须在n中添加一个。我知道你最后添加了n,但情况并不相同。 tri(n)tri(n+1)之间的差异不是一个,而是n