问题概述
最大连续区间和是一个经典的问题。给定一个长度为n的序列a[1],a[2]...a[n-1],a[n],求一个连续的子序列a[i],a[i+1]...a[j-1],a[j],使得a[i]+a[i+1]...a[j-1]+a[j]最大。
①最简单最容易想到的就是根据定义来枚举。
枚举上下界{i,j | 0<=i<=j<=n},维护一个max值即可。
其中枚举上下界的时间复杂度为O(n^2),求区间和的复杂度为O(n),所以总时间复杂度为O(n^3)。
①最简单最容易想到的就是根据定义来枚举。
枚举上下界{i,j | 0<=i<=j<=n},维护一个max值即可。
其中枚举上下界的时间复杂度为O(n^2),求区间和的复杂度为O(n),所以总时间复杂度为O(n^3)。
算法一
public int getmax(int[] a, ref int begin, ref int end)
{
int max=0;
for (int i = 1; i < a.Length; i++)
{
int sum = 0;
for (int j = i; j < a.Length; j++)
{
sum += a[j];
if (sum > max)
{
begin = i;
end = j;
max = sum;
}
}
}
return max;
}
public int getmin(int[] a,ref int begin,ref int end)
{
int min = 0;
for (int i = 1; i < a.Length; i++)
{
int sum = 0;
for (int j = i; j < a.Length; j++)
{
sum += a[j];
if (sum < min)
{
begin = i;
end = j;
min = sum;
}
}
}
return min;
}
算法二
第二个时间复杂度为 n 利用了动态规划的思维
public int max(int[] a, ref int begin, ref int end)
{
int sum = 0;
int max = 0;
int[] bit = new int[a.Length];
for (int i = 1; i < a.Length; i++)
{
if (sum <=0)
{
sum = a[i];
bit[i] = -1;
}
else
{
sum += a[i];
if(sum==0)
bit[i] = -1;
}
if (sum > max)
{
bit[i] = 1;
max = sum;
end = i;
}
}
bool ff = false;
for (int i = bit.Length - 1; i >= 0; i--)
{
if (ff && bit[i] == -1)
{
begin = i;
break;
}
if (bit[i] == 1)
{
ff = true;
}
}
return max;
}
public int min(int[] a, ref int begin, ref int end)
{
int sum = 0;
int min = 0;
int[] bit=new int[a.Length];
for (int i = 1; i < a.Length; i++)
{
if (sum >=0)
{
sum = a[i];
bit[i] = -1;
}
else
{
sum += a[i];
if(sum==0)
bit[i] = -1;
}
if (sum < min)
{
bit[i] = 1;
min = sum;
end = i;
}
} bool ff = false;
for (int i = bit.Length-1; i >= 0; i--)
{
if (ff && bit[i] == -1)
{
begin = i;
break;
}
if (bit[i] == 1)
{
ff = true;
}
} return min;
}