java 最大连续子序列和

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wlittlefive/article/details/82080610

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 : [email protected]
 * @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;
    }
}

猜你喜欢

转载自blog.csdn.net/wlittlefive/article/details/82080610