• 求最大子数组


    题目:整数数组中最大子数组的和

    要求:

    • 输入一个整形数组,数组里有正数也有负数。
    • 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。
    • 求所有子数组的和的最大值。要求时间复杂度为O(n)

    首先,想到的是既然要求这个整型数组的最大子数组之和,那么先求出所有子数组之和,再求最大。

    假设整型数组a[n],再设一个n*n整型数组arr[n][n],元素arr[i][j]表示从a[i]到a[j](包括a[j])的元素之和,

    数组有n个元素,那么一共有n(n+1)/2个子数组。即一个n*n矩阵去掉对角线的左下角。

    此时,算法的时间复杂度为O(n2)。

    废话不说,上码。

     1 #include <iostream>
     2 #include <iomanip>
     3 using namespace std;
     4 #define max_Num 100
     5 int main(int argc, char *argv[])
     6 {
     7     int arr[]={12,3,-885,4,423,-1122,115,-9,10};
     8     int max = INT_MIN;
     9     int flag_i,flag_j;
    10     int arrtemp[max_Num][max_Num]={0};
    11     for(int i = 0;i < (sizeof(arr)/sizeof(int)); i++)   //计算出所有子数列之和
    12     {
    13         for(int j=0;j < (sizeof(arr)/sizeof(int)); j++)
    14         {
    15             if(i <= j)    //arrtemp[i][j]指从arr[i]到arr[j]之和
    16             {
    17                 for(int k = i;k <= j;k++)
    18                     arrtemp[i][j] += arr[k];
    19             }
    20         }
    21     }
    22 
    23 
    24     for(int i = 0;i < (sizeof(arr)/sizeof(int)); i++)
    25     {
    26         for(int j=0;j <(sizeof(arr)/sizeof(int)); j++)
    27         {
    28             if(i <= j){
    29                 if( arrtemp[i][j] > max){
    30                     max = arrtemp[i][j];
    31                     flag_i = i;
    32                     flag_j = j;
    33                 }
    34             }
    35 
    36         }
    37     }
    38 
    39     cout <<"sum:"<< max <<"start:"<< flag_i <<"end:"<<flag_j <<endl;
    40     return 0;
    41 }

    然后,上述方法简单易于理解,但是时间复杂度上是不满足要求的

    动态规划(dynamic programming)解决

    设subarr[i]表示以arr[i]结尾 的子数组的最大子段和,即:

    subarr[i]=max{sum(arr[j~k])},其中0<=j<=i,j<=k<=i。

    因此对于数组arr[0~n]的最大字段和为max{subarr[i]},其中0<=i<n。

    在计算subarr[i]时,可以考虑以下三种情况:

    1. subarr[i] = subarr[i-1]+arr[i],当subarr[i-1]>0时,这时候的subarr[i]中包含arr[i]。
    2. subarr[i] = arr[i],当subarr[i-1]<=0,这时候以arr[i]重新作为subarr[i]的起点。
    3. subarr[i]不包含arr[i]的情况,这种情况在计算b[i]之前已经计算处结果,保存在b[0~i-1]中。最后计算max{b[i]}时会考虑到。

    实现时可以用一个临时子数组和代替subarr

    上码

     1 #include <iostream>
     2 using namespace std;
     3 #define max_Num 100
     4 int main(int argc, char *argv[])
     5 {
     6     int arr[]={12,3,-885,4,423,-1122,115,-9,10};
     7     int start,end,s,e;
     8     int sum = arr[0];
     9     int subSum = arr[0];
    10     start = 0;
    11     end = 0;
    12     s = 0;
    13     e = 0;
    14 
    15     for(int i = 1;i < (sizeof(arr)/sizeof(int));i++)
    16     {
    17         if(subSum > 0)
    18         {
    19             subSum += arr[i];
    20             e = i;
    21         }else{
    22             subSum = arr[i];
    23             s = i;
    24             e = i;
    25         }
    26 
    27         if(sum < subSum)
    28         {
    29             sum = subSum;
    30             start = s;
    31             end = e;
    32         }
    33     }
    34     cout <<"sum:"<< sum <<"    start:"<< start <<"    end:"<<end <<endl;
    35     return 0;
    36 }

    附上运行截图

  • 相关阅读:
    表单的重复提交问题
    js日期操作
    spring data jpa
    Excel Xll开发资料
    Excel DNA学习笔记一
    error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏的解决方案
    点进去勿喷
    hdu1305(字典树)
    2018 Multi-University Training Contest 3
    hihocoder 1014(字典树)
  • 原文地址:https://www.cnblogs.com/xiaoxt/p/5303601.html
Copyright © 2020-2023  润新知