今天遇到求一个整数数组的子数组的最大和,虽然网上有很多这方面的算法,但是找到了一个新的思路:
例如:数组 a = {-2,11,-4,13,-5,-2,-1},我们用一个数组Sum存放从左往右加起来的和,
如:sum[0]=-2,sum[1]=-2+11得到 sum = {-2,9,5,18,13,11,10};用数组Point存放从右往左加起来的和,但是存放时从右往左存放,得到point = {8,10,-1,5-8,-3,-1}。然后找出sum中最大的数字18,并记下下标3,找出point中的最大数字10,同样记下下标1,这两下标组合起来的就是和为最大的字数组1到3,即newArrary = {11,-4,13},和为20。
解释一下原理:sum数组中最大,则表示最大数后面的数字加起来已经不能增加整个数的值了,同理,point数组从后往前看,前面也没有加起来能大于这个值得数了,所以夹在这两者之间的即为和最大的子数组
public class Test {
static int Sum[];
static int Point[];
static void FindMaxCrossingSubarray(int a[])
{
int n = a.length;
Sum = new int[n];
Point = new int [n];
int temp=0,jk=0,mn=0,mk=0;
int h=0,k=0,j=0;
for(int i=0;i<n;i++)
{
temp = temp + a[i];
Sum[i] = temp;
}
for(int i=n-1;i>=0;i--)
{
jk =jk +a[i];
Point[i]=jk;
}
for(int i=0;i<n;i++)
{
if(Point[i]>mn)
{
mn = Point[i];
j=i;
}
}
for(int i=0;i<n;i++)
{
if(Sum[i]>h)
{
h = Sum[i];
k = i;
}
}
System.out.println("最大字数组是原数组的第"+j+"到"+k+"位");
for(int i =j;i<=k;i++)
{
mk =mk + a[i];
}
System.out.println(mk);
}
public static void main(String [] args)
{
int a[] ={-2,11,-4,13,-5,-2,-1};
FindMaxCrossingSubarray(a);
}
}