newcoder-连续子数组的最大和

newcoder-连续子数组的最大和_第1张图片

这个题目实话我第一次没有想出来,只能玩尬的过一点用例,因为我还没系统地学习动态规划以及贪心算法。
这里的题解主要参考官方的题解-逐级优化:
1.第一级:暴力做法-时间复杂度O( n 3 n^3 n3),空间复杂度O(1)
枚举左右端点然后计算总和,并实时更新最大的和。

class Solution
{
public:
  int FindGreatestSumOfSubArray(vector<int> array)
  {
      int ans = INT_MIN;
      int len = array.size();
      for (int i = 0; i < len; i++)//枚举左端点
      {
          for (int j = i; j < len; j++)//枚举右端
          {
              int now = 0;
              for (int k = i; k <= j; k++)//计算区间和-最原始的写法不同于python那么多库
              {
                  now += array[k];
              }
              ans = max(now, ans);//更新ans
          }
      }
      return ans;
  }
};

第二级-优化上述算法-因为上面的过程会重复计算很多子空间的总和,使用前缀和优化,用空间(定义一个新的数组存储和)换时间
时间复杂度 O ( n 2 ) O(n^2) O(n2) 空间复杂度 O ( n ) O(n) O(n)
写出一个优化方程:
s u m [ 1 , j ] − s u m [ 1 , i − 1 ] = = s u m [ i , j ] sum[1,j]-sum[1,i-1]==sum[i,j] sum[1,j]sum[1,i1]==sum[i,j]

class Solution{
public:
  int FindGreatestSumOfSubArray(vector<int> array)
  {

      int ans=INT_MIN;
      int len = array.size();
      vector<int> sum(len+1,0);
      //sum[0]设为空集,
      //sum[i+1]设为array[0,i]的和,其中i=0~len-1
      //约定array[-1]==0为空集
      for(int i=0;i<len;i++){
          sum[i+1]=sum[i]+array[i];//计算前缀和
      }

      for (int i = 0; i < len; i++)//约定array[-1]==0为空集
      {
          for (int j = i+1; j <= len; j++)
          {
              ans=max(ans,sum[j]-sum[i]);//计算[i-1,j-1]的和
          }
      }
      return ans;
  };
};

3.最高级-动态规划
动态规划还是讲究一个逆向思维,从最后一个数入手去推演前面已经有的和的正负需要满足什么条件。而不是去分析每一个遍历的数的正负。
算法思路:
1.设dp[n]为以第n个数为结尾,得到的子数组的和的最大值

2.因为以第n个数为结尾所以array[n]是必然被选择的

3.基于dp[n-1]的值,如果dp[n-1]>0,我们加上这个正数,我们的值是不是必然会增大

4.如果dp[n-1]<0,那么我们加上负数,我们的值就会减小,这个时候我们不如不要前面的结果,只要当前这个数,结果反而更优

5.于是我们就得到了状态转移方程 d p [ n ] = a r r a y [ n ] + ( d p [ n − 1 ] > 0 ? d p [ n − 1 ] : 0 ) dp[n]=array[n]+(dp[n-1]>0?dp[n-1]:0) dp[n]=array[n]+(dp[n1]>0?dp[n1]:0)(?:就是if-else的意思),实时跟ans比较,更新最大值即可
6.定义一个dp数组,时间复杂度 O ( n ) O(n) O(n),空间复杂度 O ( n ) O(n) O(n)–定义了一个dp数组
优化:
1.我们可以发现当前状态只跟上一个状态有关,所以我们可以只用一个int来代替dp数组,即sum

2.如果sum<0,那么这个时候就sum=array[i]

3.如果sum>0,那么就sum=sum+array[i]

4.然后实时跟allsum比较,更新最大值即可

5.时间复杂度 O ( n ) O(n) O(n) ,空间复杂度 O ( 1 ) O(1) O(1)

class Solution {
public:
    int FindGreatestSumOfSubArray(vector<int> array) {
        int sum=0;
        int allsum=INT_MIN;//全是负的就是玩尬的
        for(int i=0;i<array.size();i++){ //java size--python shape??
            if(sum<0){  
                sum=array[i];                
            }
            else{
                sum+=array[i]; //逐级叠加       
            }
            allsum=max(sum,allsum);//更新allsum
            }
            
        
        return allsum;
    }
};

你可能感兴趣的:(日常刷题记录,牛客网,动态规划,数组,C++)