1、穷举法
穷举法:
例:
1 -2 4 3 -1 -4
j=0 1到-4找最大子序列、保存下标start、end
j=1 -2到-4..
j=2 4到-4..
.
j=5
此算法遍历了所有情况、时间复杂度为O(n2)
public void find(int[] array){
int maxSum=array[0];
int currentSum=0;
int start=0;
int end=0;
for(int i=0;i<array.length;i++){
for(int j=i;j<array.length;j++){
currentSum+=array[j];
if(currentSum>maxSum){
maxSum=currentSum;
start=i;
end=j;
}
currentSum=0;
}
}
for(int i=start;i<=end;i++){
System.out.print(array[i]);
if(i!=end){
System.out.print(",");
}
}
}
2、动态规划
例:
1 -2 4 3 -1 -4
sum 1 -1 4 7 6 2
思路:动态归化时将问题化解为几个相互关联的问题、分解复杂度。
若sum[i-1]>0,则最大值为sum[i]=sum[i-1]+array[i]
否则为sum[i]=array[i]并更新start。
判断lastSum与maxSum,更新end
public static void find(int[] array){
int lastSum=0;
int maxSum=array[0];
int start=0;
int end=0;
for(int i=0;i<array.length;i++){
if(lastSum>0){
lastSum=lastSum+array[i];
}else{
lastSum=array[i];
start=i;
}
if(maxSum<lastSum){
maxSum=lastSum;
end=i;
}
}
for(int i=start;i<=end;i++){
System.out.print(array[i]);
if(i!=end){
System.out.print(",");
}
}
}
F(i)=max(F(i-1)+array[i] , array[i])
res:所有子数组的和的最大值
res=max(res,F(i))
如数组[6, -3, -2, 8, -15, 1, 2, 2]
初始状态:
F(0)=6
res=6
i=1:
F(1)=max(F(0)-3,-3)=max(6-3,3)=3
res=max(F(1),res)=max(3,6)=6
i=2:
F(2)=max(F(1)-2,-2)=max(3-2,-2)=1
res=max(F(2),res)=max(1,6)=6
i=3:
F(3)=max(F(2)+7,7)=max(1+7,7)=8
res=max(F(2),res)=max(8,6)=8
i=4:
F(4)=max(F(3)-15,-15)=max(8-15,-15)=-7
res=max(F(4),res)=max(-7,8)=8
public int FindGreatestSumOfSubArray(int[] array) {
int res=array[0];
int max=array[0];
for(int i=1;i<array.length;i++){
max=Math.max(max+array[i],array[i]);
res=Math.max(max,res);
}
return res;
}