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

第一种:常规的求解算法:使用三层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));
        }

    }
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值