首页 > 技术文章 > 求数组中最大子数组的和02

quite-love 原文

  题目:返回一个整数数组中的最大子数组的和

  要求:输入一个整形数组,有正数、有负数;

       数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和;

              将数组首尾相连;

              同时返回最大子数组的位置。

  设计思路:这个题的关键就是如何将环状数组抻直,难点就在于每一个数都可以作为数组的结束,所以,我们想了这么一个办法,例如[A,B,C,D]组成一个环状数组,那么它就可以转换为[A,B,C,D,A,B,C]的一维数组,求环状数组的子数组和的最大值就是求转换后的一维数组的子数组[A,B,C,D]、[B,C,D,A]、[C,D,B,A]以及[D,A,B,C]的和的最大值,因此可以用两个for循环实现。具体代码如下:

 1 //返回一个整数数组中最大子数组的和
 2 //有正数、有负数、数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和、将数组首尾相连、返回最大子数组的位置
 3 //张哲、张晓菲 2016/3/22
 4 
 5 #include<iostream>
 6 using namespace std;
 7 #define N 10000
 8 
 9 int main()
10 {
11     int num,arr[N];
12     int sum=0;
13     cout<<"请输入数组元素个数:";
14     cin>>num;
15     cout<<"请输入数组元素的值:";
16     for(int i=0;i<num;i++)//输入环状数组的元素值
17     {
18         cin>>arr[i];
19     }
20     for(int i=num;i<(2*num-1);i++)//将环抻直,例如环状数组值原先为[A,B,C,D],那么抻直之后为[A,B,C,D,A,B,C]
21     {
22         arr[i]=arr[i%num];
23     }
24     cout<<"环抻直之后的数组相当于:"<<endl;
25     for(int i=0;i<(2*num-1);i++)
26     {
27         cout<<arr[i]<<" ";
28     }
29     cout<<endl;
30 
31     int max=arr[0];
32     int end,start,cstart;//end为结束位置 start为起始位置
33 
34     //求子数组最大和
35     for(int j=0;j<num;j++)
36     {
37         sum=0;
38         for(int i=j;i<j+num;i++)
39         {
40             if(sum<=0)
41             {
42                 sum=arr[i];
43                 cstart=i;//当前最大子数组的起始位置
44             }
45             else
46                 sum=sum+arr[i];
47             if(sum>max)
48             {
49                 max=sum;
50                 start=cstart;
51                 end=i;
52              }
53         }
54     }
55 
56     cout<<"子数组和的最大值为:"<<max<<endl;
57     cout<<"最大子数组的起始位置为环抻直后的第"<<start+1<<"个元素,结束位置为环抻直后的第"<<end+1<<"个元素。"<<endl;
58     return 0;
59 }

测试结果如下:


  总结:这次在上次的基础上稍微做了一些修改,两个人一起,思路也多了,但是也会遇到一些问题,比如,两个人意见不一致时,如果用你的思路我就会不高兴,所以,两个人合理的沟通还是很重要的。

  时间计划日志:

  打算每天抽出晚上两个小时的时间来完成一维数组求子数组和的最大值以及环状数组求子数组和的最大值,而实际上平均一下每个程序所花费的时间并不到两个小时。

  缺陷记录日志:

  当用户输入不符合要求时,不会报错;当数的值特别大时,运行结果错误,如下图所示:

  时间记录日志:

推荐阅读