【问题标题】:Count the maximum amount of numbers in an array which sum is an even number计算数组中总和为偶数的最大数量
【发布时间】:2015-08-22 18:04:20
【问题描述】:

我有这段代码,据我了解,它在给定数组中搜索最大数量的连续数字,总和是偶数。

private static int f (int[]a, int low, int high)
{
    int res = 0;
    for (int i=low; i<=high; i++)
    res += a[i];
    return res;
}


public static int what (int []a)
{
    int temp = 0;
    for (int i=0; i<a.length; i++)
    {
        for (int j=i; j<a.length; j++)
        {
            int c = f(a, i, j);
            if (c%2 == 0)
            {
            if (j-i+1 > temp)
            temp = j-i+1;
            }
        }
    }
return temp;
} 

例如,数组 [-3,4,8,-1,15] 应该返回“4”作为答案,因为 -3+4+8-1 = 8,而 8 是偶数。

我需要一个关于如何提高效率的想法(+现在的效率是多少?O(n^3)?)

提前致谢。

【问题讨论】:

  • 提示:你只需要计算数组中有多少奇数,数组中有多少偶数。
  • 需要计算奇数和偶数的个数说 numOdd 和 numEven - 如果那个 numOdd 是偶数,那么你的答案是 (numOdd + numEven) 否则你的答案是 (numOdd + numEven - 1)

标签: java arrays performance sum


【解决方案1】:

您只需要一个循环,这将花费 O(n)。

您需要遍历数组一次并计算偶数个数和奇数个数。如果oddCount 是偶数,则输出为evenCount + oddCount,否则为evenCount + oddCount - 1

原因是所有偶数的总和是偶数。每对奇数的和也是偶数,所以元素最多的偶数和有多个元素,要么是数组的长度(如果有偶数个奇数),要么是数组的长度- 1(如果有奇数个奇数,在这种情况下,您必须从总和中排除其中一个才能得到偶数)。

其实你只需要数奇数个数:

public static int maxEvenSumLength (int []a)
{
    int oddCount = 0;
    for (int i=0; i<a.length; i++)
    {
        if (a[i] % 2 == 1) {
          oddCount++;
        }
    }
    return (oddCount % 2 == 0) ? a.length : (a.length - 1);
} 

编辑:

我错过了一个事实,即具有偶数和的元素应该是连续的。在这种情况下,如果奇数的个数是偶数,结果仍然是数组的长度。不同之处在于奇数的个数为奇数时。在这种情况下,您应该找到最接近数组两端的奇数,并且连续偶数和的长度将是最后一个奇数之前或第一个奇数之后的元素数(两者中的较大者)。

public static int maxConsecutiveEvenSumLength (int []a)
{
    int oddCount = 0;
    int firstOddIndex = -1;
    int lastOddIndex = a.length;
    for (int i=0; i<a.length; i++)
    {
        if (a[i] % 2 == 1) {
          oddCount++;
          if (firstOddIndex < 0)
              firstOddIndex = i;
          lastOddIndex = i;
        }
    }
    if (oddCount % 2 == 0) {
        return a.length;
    } else {
        return Math.max(a.length - firstOddIndex - 1,lastOddIndex);
    }
} 

我们仍然在数组上迭代一次,所以时间复杂度仍然是 O(n)。

【讨论】:

  • 刚刚注意到这个方法没有考虑数组中数字的顺序。方法“what”按顺序扫描数组并查看连续数字的总和是否为偶数。
  • @AlexyGrabov 哦,我错过了连续的部分。
  • 所以你基本上是在移动 2 个指针,一个从数组的开头开始,一个从结尾,然后向中间移动。当循环结束时,你让它们指向 2 个角的奇数。我没有得到的最​​后一部分 - “连续偶数和的长度将是最后一个奇数之前或第一个奇数之后的元素数(两者中的较大者)。”不过,代码可以工作:)
  • @AlexyGrabov 我的意思是,如果您有奇数个奇数元素,例如1 2 3 4 5 6,则具有偶数和的最长连续序列将是1 2 3 4(之前的所有元素最后一个奇数,即 5)或2 3 4 5 6(第一个奇数之后的所有元素,即 1)。您取这两个序列中较长的一个,在本例中长度为 5。
  • 对,只是在回家的路上想了想,明白了代码的工作原理。非常感谢!
猜你喜欢
  • 2021-03-10
  • 2022-10-17
  • 2020-05-13
  • 1970-01-01
  • 1970-01-01
  • 2020-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多