• 求最大子数组


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

    要求:

    • 输入一个整形数组,数组里有正数也有负数。
    • 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。
    • 求所有子数组的和的最大值。要求时间复杂度为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 = INT_MIN;
     9     int subSum =INT_MIN;
    10     start = 0;
    11     end = 0;
    12     s = 0;
    13     e = 0;
    14 
    15     for(int i = 0;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 }
    

      截图如下:

  • 相关阅读:
    Idea中提交SVN或git时,忽略某些文件不提交
    SVN(subversion )服务端和客户端的下载安装使用
    layui官方文档
    使用IntelliJ IDEA配置Tomcat
    IntelliJ IDEA 配置JDK
    设置 IntelliJ IDEA 主题
    mybatis+mysql批量插入和批量更新
    session.资料
    MyEclipse2014.Maven自动更新
    Office.资料
  • 原文地址:https://www.cnblogs.com/liuwei8882/p/5323232.html
Copyright © 2020-2023  润新知