题目描述:
输入一个整型数组,数组里有正数也有负数。
数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。
求所有子数组的和的最大值。要求时间复杂度为O(n)。
例如输入的数组为1, -2, 3, 10, -4, 7, 2, -5,和最大的子数组为3, 10, -4, 7, 2,
因此输出为该子数组的和18。
子问题为以当前元素结尾的序列最大和
//递归方法:任何递推公式都能转化为递归.
public int maxSum(int []data,int n)
{
if(n==0)
return data[0];
if(maxSum(data,n-1)<=0)
return data[n];
else
return maxSum(data,n-1)+data[n];
}
//自顶向下记忆化方法
//用一个数组存放计算的值;
public int []b=new int[]{-100,-100,-100,-100,-100,-100,-100,-100,-100,-100};
public int maxSum1(int []data,int n)
{
if(n==0)
{
b[0]= data[0];
return b[0];
}
if(b[n-1]==-100)//用数组记忆化的方法!!!!!!
{
b[n-1]=maxSum(data,n-1);
}
if(b[n-1]<=0)
{
b[n]=data[n];
}
else
{
b[n]=b[n-1]+data[n];
}
return b[n];
}
//DP_自底向上的方法;index存放最大和子序列的首末下标。
public void maxSum_DP(int []data,int n,int []index)
{
int start=0;
int end=0;
int temp=0;
int maxsum=0;
int []b=new int [data.length];
b[0]=data[0];//第一个为他自己,因前边没有数,不能放入递推公式中;
for(int i=0;i<n-1;i++)
{
if(b[i]<=0)
{
b[i+1]=data[i+1];
//只有此时才更新temp
temp=i+1;
}
else
b[i+1]=b[i]+data[i+1];
//更新坐标;
if(b[i+1]>maxsum)
{
maxsum=b[i+1];
start=temp;
end=i+1;
}
}
index[0]=start;
index[1]=end;
}