数组中连续序列和最大值(循环数组)

今天遇到一个问题,数组连续子序列

类似leetcode 53 但略微不同,是循环数组

如果一个数组 [-2,1,-3,4,-1,2,1,-5,4] 返回连续子数组最大和

方法一,暴力循环,复杂度较高,不多介绍

方法二,贪心法
int main()
{
    vector<int>arr;
    //输入数据
    int m;
    cin>>m;
    for(int i=0;i<m;i++)
    {
        int tmp;
        cin>>tmp;
        arr.push_back(tmp);
    }

    //贪心
    int result = INT_MIN;
    int sum=0;
    for(int i=0;i<arr.size();i++)
    {
        sum+=arr[i];
        result = max(sum,result);
        //小于0重新判断大小
        if(sum<0)
        {
            sum=0;
        }

    }

    cout<<result<<endl;
    return 0;
}

 这样解决很常见,但遇到的问题是循环数组,可以从尾部到头部寻找最大和  参考leetcode 918 环形子数组最大和

 举例,输入[4,-3,2,-6,2] 最大和是尾部 2 和头部 4 的和 。解

 解决方法

  将数组重复拼接到尾部,分别使用上面的方法求出,0 ~ n,1 ~ n+1,2 ~ n+2,...,n-1 ~ 2*n-1 最大和,取其中最大的。

  复杂度o(n2)复杂度过高,看到有一个解法,是求出最大和maxsum,最小和minsum,数组总和sum。

  结果为max(maxsum,(sum-minsum));

  代码如下:

  

#include<iostream>
#include<vector>
using namespace std;
int main()
{
    vector<int>arr;
    //输入数据
    int arrsum=0;
    int m;
    cin>>m;
    for(int i=0;i<m;i++)
    {
        int tmp;
        cin>>tmp;
        arrsum+=tmp;
        arr.push_back(tmp);
    }

    //贪心
    int result = INT_MIN;
    int sum=0;
    for(int i=0;i<arr.size();i++)
    {
        sum+=arr[i];
        result = max(sum,result);
        //小于0重新判断大小
        if(sum<0)
        {
            sum=0;
        }

    }

    //求出最小值
    int minresult  = INT_MAX;
    int minsum = 0;
    for(int i=0;i<arr.size();i++)
    {
        minsum+=arr[i];
        minresult = min(minresult,minsum);
        if(minsum>0)
        {
            minsum = 0;
        }

    }
  
  //2022 3.9更新,如果全负数则直接返回


  if(result<0){
    return result;
  } int maxout=0; //循环数组的最大和为 max(最大和,总和-最小和) maxout = max(result,(arrsum-minresult)); cout<<maxout<<endl; return 0; }

  其他方法待续 



posted @ 2020-10-11 23:49  海拉尔  阅读(446)  评论(0编辑  收藏  举报