我有这个代码,根据我的理解,它搜索给定数组中的最大连续数字量,该总和是偶数。
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)?)
提前致谢。
答案 0 :(得分:3)
您只需要一个循环,这将需要O(n)。
您需要迭代一次数组并计算偶数的数量和奇数的数量。如果evenCount + oddCount
为偶数,则您的输出为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)。