Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/276.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
C# 时间复杂性-将O(N²;)重构为O(N)_C#_Arrays_Algorithm_Big O_Time Complexity - Fatal编程技术网

C# 时间复杂性-将O(N²;)重构为O(N)

C# 时间复杂性-将O(N²;)重构为O(N),c#,arrays,algorithm,big-o,time-complexity,C#,Arrays,Algorithm,Big O,Time Complexity,我这里有一个函数,它计算数组中唯一整数对的数量,谁的和是偶数。目前,我已经使用嵌套循环对此进行了编码,但是这是低效的,因为嵌套循环会导致时间复杂度O(N²) 在本例中,A表示数组,p和Q表示整数对Q应始终大于P,否则会导致非唯一整数对(其中P和Q可以指向数组中的相同值) public int GetEvenSumCount(int[]A) { //结果存储 int结果=0; //循环遍历每个数组元素以获得P 对于(int P=0;P

我这里有一个函数,它计算数组中唯一整数对的数量,谁的和是偶数。目前,我已经使用嵌套循环对此进行了编码,但是这是低效的,因为嵌套循环会导致时间复杂度
O(N²)

在本例中,
A
表示数组,
p
Q
表示整数对
Q
应始终大于
P
,否则会导致非唯一整数对(其中P和Q可以指向数组中的相同值)

public int GetEvenSumCount(int[]A)
{
//结果存储
int结果=0;
//循环遍历每个数组元素以获得P
对于(int P=0;P

我现在需要重构它,以便更糟糕的案例时间复杂性是
O(N)
,但我不知道从哪里开始!我知道这将涉及只使用一个循环,而不是嵌套循环,但我不知道在这方面如何将
a[P]
a[Q]
求和。

只有当两个整数都是奇数或偶数时,两个整数的和才能是偶数

扫描数组,并计算奇数和偶数。假设它们是N1和N2

The number of pairs = (N1 Choose 2) + (N2 Choose 2).
                    = N1*(N1-1)/2 + N2*(N2-1)/2

您可以通过两种方式获得偶数和:

  • 添加两个偶数值,如
    2+4=6
  • 添加两个奇数,如
    1+3=4
  • 相反,将偶数值与奇数值相加将始终是奇数,如
    1+2=3

    所以你能得到的偶数和的总数是:

  • 偶数值对的数目
  • 加上,奇数对的数目
  • n
    项集合中的对数为:

    N = n * (n-1) / 2
    
    完整代码:

    static bool IsEven(int i)
    {
        return i % 2 == 0;
    }
    
    static bool IsOdd(int i)
    {
        return i % 2 != 0;
    }
    
    static int GetPairCount(int n)
    {
        return n * (n- 1) / 2;
    }
    
    public static int GetEvenSumCount(int[] A)
    {
        int evensCount = A.Count(IsEven);
        int oddCount = A.Count(IsOdd);
    
        return GetPairCount(evensCount) + GetPairCount(oddCount);
    }
    
    如您所见,没有嵌套循环,您不需要实际计算总和


    此实施的复杂性为O(N)。

    如承诺的那样,报告解决方案:

    static int GetEvenSumCountFast(int[] A)
    {
        int[] OddEven = new int[2];
        for (int i = 0; i < A.Length; i++)
            OddEven[A[i] & 1]++;
        return OddEven[0] * (OddEven[0] - 1) / 2 +
            OddEven[1] * (OddEven[1] - 1) / 2;
    }
    
    static int GetEvenSumCountFast(int[]A)
    {
    int[]奇偶=新的int[2];
    for(int i=0;i
    其他人已经解决了,但不管怎样

    备选方案:

    static int GetEvenSumCountFast(int[] A)
    {
        int odd = 0, even = 0;
        for (int i = 0; i < A.Length; i++)
        {
            odd += A[i] & 1;
            even += ~A[i] & 1;
        }
        return odd * (odd - 1) / 2 +
            even * (even - 1) / 2;
    }
    
    static int GetEvenSumCountFast(int[]A)
    {
    int奇数=0,偶数=0;
    for(int i=0;i
    由于两个偶数之和是偶数,两个奇数之和也是偶数(但奇数和偶数之和是奇数),我首先将它们分为偶数和奇数:

    var grouped = A.GroupBy(x => x % 2 == 0);
    
    现在,每组中唯一对的数量(n为元素数量)为:

    (n-1) + (n-2) + … + 1 = n * (n-1) / 2
    
    因此(如果我们是偶数或奇数组,则独立):


    感谢所有对这个问题做出贡献的人,我在这里记下了你们所有的笔记,并生成了一个简明的函数,它的行为符合预期,并且仍然符合所需的O(N)时间复杂性

    public int GetEvenSumCount(int[] A)
    {
        int odd = A.Count(o => o % 2 != 0);
        int even = N.Length - odd;
        return odd * (odd - 1) / 2 + even * (even - 1) / 2;
    }
    

    问题是找到唯一的偶数和…在上述所有解决方案中…当计算奇数和偶数时,它们没有考虑到它们的唯一性。例如,如果有两个偶数具有相同的值,比如4和另一个偶数6。将有两个偶数和具有值10,它们是非唯一的,我得到了一个解,它是O(n)。有点你可以认为这是作弊。可能是的

    “int”的范围有限-+/-2^31

    我们必须假设可能的数组大小是无限的——否则O()表示法就没有意义了。如果数组大小被限制为2^64个元素,那么问题总是可以通过使用2^128个操作在恒定时间O(1)内解决

    因此,创建一个包含数组中所有可能的2^32 int值的位图。这需要O(n)步。从位图创建一个新数组,并删除所有重复项。该数组最多有min(n,2^32)个条目。其余的操作始终可以在2^64个操作中完成,即O(1)。所以总数是O(n),但是如果n在2^32左右,则有一个巨大的常数因子

    如果数组包含字节而不是整数,那么这实际上是一个相当快的算法


    现在找到一个有效的算法,这似乎有点困难

    显然,你不能通过明确访问每一对来做到这一点。但你不必这么做。将报告解决方案。这可能不是Twitter的采访问题,对吧?@templatetypedef,这是采访问题,但不是Twitter的采访问题。嗨,我注意到你有一个“快速”的例子。这比O(N)时间复杂度快吗?不,它们都是O(N)-“快”,因为它们比O(N^2)快。你不能在少于O(N)的时间内完成它,最坏的情况是你必须查看所有的输入。感谢这个答案,它帮助了很多!你能解释一下你为什么这样做:N1*(N1-1)/2+N2*(N2-1)/2吗?我知道这是可行的,但我不明白这是在做什么?这是你可以从n个项目中选择2个项目的方式,而不必考虑顺序。C(n,2)。要获得更多信息,你可以在谷歌上搜索排列和组合,或者访问这个链接。我明白你的意思,但这“可能”并不重要。此外,这是一个面试问题,上面的答案仍然是错误的!:-PP.S。实际上有四个偶数和的值是10,而不是2…为什么?第1个4和第1个6、第1个4和第2个6、第2个4和第1个6、第2个4和第2个6:-)
    return gouped.Sum(x => {var n = x.Count(); return n * (n-1) / 2; });
    
    public int GetEvenSumCount(int[] A)
    {
        int odd = A.Count(o => o % 2 != 0);
        int even = N.Length - odd;
        return odd * (odd - 1) / 2 + even * (even - 1) / 2;
    }