最大连续子序列的四种求解方法

来源:互联网 发布:淘宝财务运营分析 编辑:程序博客网 时间:2024/06/05 00:42

第一种:常规的求解算法:使用三层for循环,然后进行比较得到最大值最后进行返回即可 第一层for循环确定开始的子序列的位置 第二次for循环确定结束的子序列的位置 第三层for循环进行求和相加 if判断进行求和比较返回较大的子序列的和

package 最大子序列求和方法一;public class MaxSum01 {    public static int MaxSum(int[] A){         int ThisSum;         int MaxSum = 0;         int N = A.length;         for (int i = 0; i < N; i++) {            for(int j = i; j < N; j++){                ThisSum = 0;                for(int k = i; k <= j; k++){                    ThisSum += A[k];                }                if (ThisSum > MaxSum) {                    MaxSum = ThisSum;                }            }        }        return MaxSum;    }    public static void main(String[] args){        int[] array = {4,-3,5,-2,-1,2,6,-2};        int result = MaxSum(array);        System.out.println(result);    }}

第二种方法,其实和第一种思路实现差不多,不过他的时间复杂读降低了,同理第一个for循环仍然是寻找子序列的开始位置,第二个for循环直接寻找子序列的结束位置然后直接进行求和计算,然后最后进行if比较进行交换

package 最大子序列求和方法一;public class MaxSum02 {    public static int MaxSum(int[] A){        int MaxSum = 0;        int ThisSum;        for (int i = 0; i < A.length; i++) {            ThisSum = 0;            for(int j = i; j < A.length; j++){                ThisSum += A[j];                if (ThisSum > MaxSum) {                    MaxSum = ThisSum;                }            }        }        return MaxSum;    }    public static void main(String[] args){        int[] array = {4,-3,5,-2,-1,2,6,-2};        int result = MaxSum(array);        System.out.println(result);    }}

第三种方法,使用递归来实现,我们把需要求解的问题进行分析,最大子序列只可能出现在数组的三个位置:第一个是子序列的左边 第二个是子序列的右边,第三个是子序列的中间部分,对于前两种情况,我们采用递归来实现,第三种情况我们可以通过求出前半部分的最大和(包含前半部分的最后一个元素)以及后半部分的最大和(包含后半部分的第一个元素)而得到,然后将这两个和加在一起即可。这就是我们采用递归实现的基础思路,下面开始直接码代码

package 最大子序列求和方法一;public class MaxSum03 {    public static int MaxSum(int[] A,int left,int right){        int maxLeftSum,maxRightSum;        int MaxSum = 0;        int maxLeftBorderSum = 0,maxRightBorderSum = 0;        int leftBorderSum = 0;        int rightBorderSum = 0;        if (left == right) {            return A[left] > 0 ? A[left] : 0;        }         int center = (left + right)/2;         maxLeftSum = MaxSum(A,left,center);         maxRightSum = MaxSum(A,center + 1,right);        for(int i = center; i >= left; i --){            leftBorderSum += A[i];            if (leftBorderSum > maxLeftBorderSum) {                maxLeftBorderSum = leftBorderSum;            }            }        for(int i = center + 1; i <=  right; i++){            rightBorderSum += A[i];            if (rightBorderSum > maxRightBorderSum) {                maxRightBorderSum = rightBorderSum;            }        }        return max(maxLeftBorderSum,maxRightBorderSum,maxLeftBorderSum + maxRightBorderSum);    }    private static int max(int a, int b, int c) {        if(a > b && a > c){            return a;        }        if(b > a && b > c){            return b;        }        else {            return c;        }    }    public static void main(String[] args){        int[] array = {4,-3,5,-2,-1,2,6,-2};        int result = MaxSum(array,0, array.length - 1);        System.out.println(result);    }}

第四种是采取动态规划实现的:主要思路是这样的,当前求和的值为负数此时我们采取的操作是直接赋值为0,这样采用动态规划很好的解决了这道题

package 最大子序列求和方法一;public class MaxSum04 {    public static int MaxSum(int[] A){        int maxSum = 0;        int thisSum  = 0;        for (int i = 0; i < A.length; i++) {            thisSum += A[i];            if(thisSum > maxSum){                maxSum = thisSum;            }            else if(thisSum < 0){                thisSum = 0;            }        }        return maxSum;    }        public static void main(String[] args) {            // TODO Auto-generated method stub             int[] a={4,-3,5,-2,-1,2,6,-2};             System.out.println(MaxSum(a));        }    }
阅读全文
1 0