import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 书上的例子,自己写一遍加深理解
* 功能 : 最大连续子序列之和
* 描述 :已知包含n个元素的数组,设计算法找出一个连续子序列A[i]....A[j],使其元素之和最大
* 例子: {-2,11,-4,13,-5,2} ->20;
* date : 2018/8/26
*
* @author : zcwang@wisdombud.com
* @version : 0.0.4-snapshot
* @creed : code is card for me
* @since : JDK 1.8
*/
public class MaxSerialSubSequenceSum {
private final static Logger LOGGER = LoggerFactory.getLogger(MaxSerialSubSequenceSum.class);
public static void main(String args[]) {
int[] a={-2,11,-4,13,-5,2};
int[] b={-2,-11,-4,-13,-5,-2};
System.out.println(maxSerialSum(b,b.length));
System.out.println(maxSerialSum1(a,a.length));
System.out.println(maxSerialSum2(a,a.length));
System.out.println(maxSerialSum3(b,b.length));
}
/**
* 暴力法 时间复杂度 O(n的三次方)
* @param a 原始数组
* @param n 数组长度
* @return
*/
public static int maxSerialSum(int a[],int n){
int max=Integer.MIN_VALUE;
for (int i=0;i<n;i++){ // 每一个可能开始的起点
for (int j = i; j < n; j++) { // 每一个可能结束的点
int sum=0;
for (int k = i; k <= j; k++) { //计算在起点到结束点的和
sum+=a[k];
}
if (sum>max){
max=sum;
}
}
}
return max;
}
/**
* 时间复杂度 O(n的平方)
* @param a
* @param n
* @return
*/
public static int maxSerialSum1(int a[],int n){
int max=0;
for (int i = 0; i < n; i++) { //起点
int sum=0;
for (int j = i; j < n; j++) { //终点
sum+=a[j];
if (sum>max){
max=sum;
}
}
}
return max;
}
/**
* 时间复杂度O(n) 空间复杂度O(n)
* @param a
* @param n
* @return
*/
public static int maxSerialSum2(int a[],int n){
int max=0;
int tem[]=new int[n];
for (int i = 0; i < n; i++) {
tem[i]=0;
}
if (a[0]>0){
tem[0]=a[0];
}else {
tem[0]=0;
}
for (int i = 1; i < n; i++) {
//这里如果小于0 在加后面的就没有意义了。
//如果加一负数也不用担心会影响结果,因为tem[i-1]中已经存了没加这个负数时的值,
//如果后面的结果不大于tem[i-1] 那么会返回tem[i-1]的值。
if (tem[i-1]+a[i]>0){
tem[i]=tem[i-1]+a[i];
}else {
// 如果结果小于0 那么就以i为起点算后面的
tem[i]=0;
}
}
for (int i = 0; i < n; i++) {
if (tem[i]>max){
max=tem[i];
}
}
return max;
}
/**
* 思路 :从头开始加,如果结果小于0 就置为0 ,sumSoFar 用来保存 整个过程中出现的最大值 即结果
* @param a
* @param n
* @return
*/
public static int maxSerialSum3(int a[],int n){
boolean flag=false;
int max=Integer.MIN_VALUE;
for (int i = 0; i < n; i++) {
if (a[i]>0){
flag=true;
break;
}
if (a[i]>max){
max=a[i];
}
}
if (!flag){
return max;
}
int sumSoFar=0;
int sumEndingHere=0;
for (int i = 0; i < n; i++) {
sumEndingHere=sumEndingHere+a[i];
if (sumEndingHere<0){
sumEndingHere=0;
continue;
}
if (sumEndingHere>sumSoFar){
sumSoFar=sumEndingHere;
}
}
return sumSoFar;
}
}