最大子序列求和问题java实现

问题

给定一个整数序列,其中包含正负数,求该序列中所有连续子序列的最大和

解法1

思路:使用暴力解法,将所有可能的结果全部计算出来,然后找出其中的最大子序列
存在问题:具有大量的重复计算
时间复杂度:O(n^3)

java代码:

public static int[] getMaxChildArrayOne(int[] arr){

        int[] maxChildArray = null;

        int start = 0;//开始位置
        int end = 0;//结束位置
        int maxSum = 0;//最大值

        //循环遍历整个数组
        for(int i=0;i<arr.length;i++){

            //数组每次计算之后向后移动
            for(int j=i;j<arr.length;j++){

                //记录当前和
                int thisSum = 0;

                //每次从头开始计算当前数组所有可能的子序列组合
                //存在大量重复计算
                for (int k=i;k<=j;k++){

                    //计算求和
                    thisSum += arr[k];

                    if (thisSum>maxSum){
                        //记录开始位置
                        start=i;
                        //记录结束位置
                        end=k;
                        //更新最大值
                        maxSum = thisSum;
                    }
                }
            }
        }
        maxChildArray = Arrays.copyOfRange(arr,start,end+1);
        return maxChildArray;
    }

解法2

思路:由解法一可知,第二个for循环和第三个for循环存在着大量的重复计算,所以可以减少重复计算,去掉一次for循环
比如:计算arr[0] 到 arr[3] , 上面的解法会计算 arr[0] , arr[0]+arr[1] , arr[0] + arr[1] +arr[2] , arr[0] + arr[1] +arr[2]+arr[3] ,后面的每次计算都包含前面已经计算过的值
时间复杂度:O(n^2)

java代码:

public static int[] getMaxChildArrayTwo(int[] arr){

        int[] maxChildArray = null;
        int start = 0;
        int end = 0;
        int maxSum = 0;
        for (int i = 0; i < arr.length; i++) {

            //当前子序列和
            int thisSum = 0;
            //依次向后移动一位,遍历剩余序列
            for (int k=i;k<arr.length;k++){

                //求和
                thisSum += arr[k];

                if (maxSum<thisSum){

                    start = i;
                    end = k;
                    maxSum = thisSum;
                }
            }
        }
        maxChildArray = Arrays.copyOfRange(arr,start,end+1);
        return maxChildArray;

    }

解法3

思路: 由每次计算得到的子序列和thisSum ,如果thisSum<= 0,则说明最大子序列一定不包含当前计算的子序列,即可以舍弃掉当前的子序列从下一个重新开始计算
时间复杂度:O(n)

java代码实现

public static int[] getMaxChildArrayThree(int[] arr){

        int[] maxChildArray = null;
        int start = 0;
        int end = 0;
        int maxSum = 0;

        int thisSum = 0;

        //只需要一次遍历
        for (int i = 0; i < arr.length; i++) {

            //求和
            thisSum += arr[i];

            //前面计算的总和<=0,所以最大子序列不可能包含已经计算过的子序列
            if (thisSum<=0){
                //最大子序列下标从下个开始计算
                start = i+1;
                //当前和置为 0
                thisSum = 0;
            }

            if (thisSum>maxSum){

               //结束位置为当前计算的子序列和的最后一个下标
                end = i;
                maxSum = thisSum;
            }
        }
        maxChildArray = Arrays.copyOfRange(arr,start,end+1);
        return maxChildArray;

    }
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值