package 分而治之;
import utils.Utils;
public class 数组最大子序列和 {
//time O(n^3) space O(1)
public static int getMaxSumOfSequence01(int[] a){
int maxsofar = 0;
int startIndex = 0,endIndex = 0;
for(int i=0;i<a.length;i++){
for(int j=0;j<a.length;j++){
int sum = 0;
for(int k=i;k<=j;k++)
sum+=a[k];
if(maxsofar<=sum){
startIndex = i;
endIndex = j;
}
maxsofar = Math.max(sum, maxsofar);
}
}
System.out.println("["+startIndex+","+endIndex+"]");
return maxsofar;
}
//time O(n^2) space O(1)
public static int getMaxSumOfSequence02(int[] a){
int maxsofar = 0;
int startIndex = 0,endIndex = 0;
for(int i=0;i<a.length;i++){
int sum = 0;
for(int j=i;j<a.length;j++){
sum+=a[j];
if(maxsofar<=sum){
startIndex = i;
endIndex = j;
}
maxsofar = Math.max(sum, maxsofar);
}
}
System.out.println("["+startIndex+","+endIndex+"]");
return maxsofar;
}
//time O(n) space O(1)
public static int getMaxSumOfSequence04(int[] a){
int maxsofar = 0;
int sum = 0;
int startIndex = 0,endIndex = 0;
for(int i=0;i<a.length;i++){
sum+=a[i];
if(sum<=0) {
sum = 0;
startIndex = i+1;
} else {
if(maxsofar<=sum){
endIndex = i;
}
maxsofar = Math.max(sum, maxsofar);
}
}
System.out.println("["+startIndex+","+endIndex+"]");
return maxsofar;
}
//time O(n^2) space O(n)
public static int getMaxSumOfSequence03(int[] a){
int maxsofar = 0;
int startIndex = 0,endIndex = 0;
int[] currnum = new int[a.length];
currnum[0] = a[0];
for(int i=1;i<a.length;i++)
currnum[i] = currnum[i-1]+a[i];
for(int i=0;i<a.length;i++){
int sum = 0;
for(int j=i;j<a.length;j++){
if(i==0) sum = currnum[j];
else sum = currnum[j] - currnum[i-1];
if(maxsofar<=sum){
startIndex = i;
endIndex = j;
}
maxsofar = Math.max(sum, maxsofar);
}
}
System.out.println("["+startIndex+","+endIndex+"]");
return maxsofar;
}
//O(log(n))
public static int getMaxSumOfSequeneceByRecursion(int[] a,int l,int r)
{
int lmax,rmax,sum=0;
int mid = (l+r)/2;
if(l>r) //zero item
return 0;
if(l==r) //only one item
return Math.max(a[l], 0);
lmax = sum = 0;
for(int i=mid;i>=l;i--){
sum+=a[i];
lmax = Math.max(lmax, sum);
}
rmax = sum = 0;
for(int i=mid+1;i<=r;i++){
sum+=a[i];
rmax = Math.max(rmax, sum);
}
return Utils.maxOfThree(lmax+rmax,getMaxSumOfSequeneceByRecursion(a,l,mid),getMaxSumOfSequeneceByRecursion(a,mid+1,r));
}
public static void main(String[] args) {
//int a[] = {31,-41,59,26,-53,58,97,-93,-23,84};
int a[] = Utils.produceNum(-10000, 10000, 10000);
long t1 = System.nanoTime();
System.out.println(getMaxSumOfSequence01(a));
long t2 = System.nanoTime();
System.out.println("m1 time:"+(t2-t1)/1000);
System.out.println(getMaxSumOfSequence02(a));
long t3 = System.nanoTime();
System.out.println("m2 time:"+(t3-t2)/1000);
System.out.println(getMaxSumOfSequence03(a));
long t4 = System.nanoTime();
System.out.println("m3 time:"+(t4-t3)/1000);
System.out.println(getMaxSumOfSequence04(a));
long t5 = System.nanoTime();
System.out.println("m4 time:"+(t5-t4)/1000);
System.out.println(getMaxSumOfSequeneceByRecursion(a,0,a.length-1));
long t6 = System.nanoTime();
System.out.println("m5递归 time:"+(t6-t5)/1000);
}
}