【题 42 连续子数组的最大和】

【题目】
HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{1,-2,3,10,-4,7,2,5},连续子向量的最大和为8(从第0个开始,到第3个为止)。给一个数组,返回它的最大连续子序列的和,你会不会被他忽悠住?(子向量的长度至少是1)
【思路】
解法一举例分析数组的规律
从第一个数字开始相加,如果累加的和小于0,则抛弃之前的数字,从下一个数字开始加。
在这里插入图片描述
【实现】

public class Solution {
    public int FindGreatestSumOfSubArray(int[] array) {
        int len = array.length;//输入数组长度
        if(len == 0){
            return 0;
        }
        int curSum = array[0];//加到当前数字的和
        int maxSum = array[0];//目前最大子向量和
        for(int i = 1;i < len;i++){
            if(curSum > 0){//如果当前的和大于0
                curSum += array[i];//继续加
            }else{//否则
                curSum = array[i];//重新开始
            }
            if(curSum >maxSum){//如果当前的和大于目前的最大子向量的和
                maxSum = curSum;//交换
            }
        }
        return maxSum;
    }
}

在这里插入图片描述
**解法二:应用动态规划法 **
f(i)表示以第i个数字结尾的子数组的最大和
f(i):
f(i) = pData[i] i = 0或者f(i-1) <= 0
f(i) = f(i-1) + pData[i] i 不等于 0并且f(i-1) > 0

公式的意义:
· 当以第i-1个数字结尾的子数组中所有数字的和小于0时,如果把这个负数与第i个数累加,则得到的结果比第i个数字本身还要小,所以这种情况下以第I个数字结尾的子数组就是第I个数字本身。
· 如果以第i-1个数字结尾的子数组中所有数字的和大于0,则与第i个数字累加就得到以第i个数字结尾的子数组中所有数字的和。

【实现】

public static int FindGreatestSumOfSubArray(int[] array) {
           int len = array.length;
           if (len == 0){
            return 0;
           }
           int[] currentsum = new int[len];
           currentsum[0] = array[0];
           int greatsetsum = array[0];
           System.out.println("第1步:累加子数组和:"+currentsum[0]+",最大子数组和:"+greatsetsum);
           for(int i=1;i<array.length;i++){
                //下面是动态规划的状态转移方程
                if(currentsum[i-1]>0){
                    currentsum[i] = currentsum[i-1] + array[i];
                }else{
                    currentsum[i] = array[i];
                }
                //根据currentsum的值更新greatsetsum的值
                if(currentsum[i] > greatsetsum){
                    greatsetsum  = currentsum[i];
                }
               System.out.println("第"+(i+1)+"步:累加子数组和:"+currentsum[i]+",最大子数组和:"+greatsetsum);
           }
           return greatsetsum;
    }

参考:
1.《剑指offer》
2.https://blog.csdn.net/kongmin_123/article/details/82430985

猜你喜欢

转载自blog.csdn.net/weixin_39795049/article/details/88573349