连续子数组的最大和

HZ偶尔会拿些专业问题来忽悠那些非计算机专业的学生。今天测试组开完会后,他又发话了:在古老的以为模式识别中,常常需要计算最长子向量的最大和,当向量全为正数时,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数取弥补他呢?例如,{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,第3个结束).给定一个数组,返回他的最大连续子序列的和,你会不会被他忽悠住(连续子向量的长度至少为1)。

题解:
对于此题,有两种方法。为暴力穷举和动态规划。
1)暴力穷举:
对于输入的数组,可以设置一个相同大小的数组,进行遍历。
对于一个长为n的输入,设置一个长为n的数组arr,而arr[0]表示为第0个数的值,arr[1]=array[1]+arr[0],即表示arr[1]为以第0个数为始,第1个数为终的子序列的和,arr[i]=array[i]+arr[i-1]表示以开始为0,终于i个数的子序列的和。
遍历更新始点不同、终点不同的子序列,最终得到穷举子序列中最大和。
代码如下:

class Solution {
public:
    int FindGreatestSumOfSubArray(vector<int> array) {
        int res;
        if(array.size()==0)
            return 0;//返回长度为0的数组
        int *arr=new int[array.size()]{0};
        res=array[0];
        for(int i=0;i<array.size();i++){//遍历始点
            int temp=array[0];
            for(int j=i;j<array.size();j++){//遍历终点
                if(j==i){//更新点
                    arr[j]=array[j];
                    if(temp<arr[j])
                        temp=arr[j];
                }
                else{//更新数组数据
                    arr[j]=array[j]+arr[j-1];
                    if(temp<arr[j])
                        temp=arr[j];
                }
            }
            if(res<temp)
                res=temp;
        }
        delete[] arr;
        return res;
    }
};

2)动态规划:
从前往后进行遍历,对于第i个数,当前面序列相加的数据大于0时,则表示对最大值是有贡献的,如果是小于0,则表示相加会小于第i个数,对最大值没有贡献,并会减小。因此直接舍弃第i个数前面的数据,不断进行更新,得到最终答案。
代码如下:

class Solution {
public:
    int FindGreatestSumOfSubArray(vector<int> array) {
        /*int res;
        if(array.size()==0)
            return 0;
        int *arr=new int[array.size()]{0};
        res=array[0];
        for(int i=0;i<array.size();i++){
            int temp=array[0];
            for(int j=i;j<array.size();j++){
                if(j==i){
                    arr[j]=array[j];
                    if(temp<arr[j])
                        temp=arr[j];
                }
                else{
                    arr[j]=array[j]+arr[j-1];
                    if(temp<arr[j])
                        temp=arr[j];
                }
            }
            if(res<temp)
                res=temp;
        }
        delete[] arr;
        return res;*/
        int res;
        if(array.size()==0) return res;
        if(array.size()==1) return array[0];
        res=array[0];
        int num=array[0];
        for(int i=1;i<array.size();i++){
            num=max(num+array[i],array[i]);
            res=max(num,res);
        }
        return res;
    }
};
Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐