软件工程结对开发之求一个或者多个数组中连续最大子数组之和3
一、题目要求
题目:返回一个整数数组中最大子数组的和。
要求:
输入一个整形数组,数组里有正数也有负数。
数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。
如果数组A[0]……A[j-1]首尾相邻,允许A[i-1], …… A[n-1], A[0]……A[j-1]之和最大。
同时返回最大子数组的位置。
求所有子数组的和的最大值。要求时间复杂度为O(n)。
二、设计思想
在上次用动态规划法求一维数组的最大连续子数组之和的基础上,对于首尾相邻的数组,我们可以求出以第一个元素为起始的数组的最大连续子数组,接着求出以第二个元素为起始的数组的最大连续子数组,依次求出各最大连续子数组,在一一比较,由此可以求出首尾相邻的最大连续子数组,保存其起始坐标和结束坐标,方便输出。
三、代码
#include <iostream.h> void Arr_Maxsum(int arr[],int length,int first,int last) { int count=0; int result=arr[0]; int sum=arr[0]; for(int i=0;i<length;i++) { sum=0; for(int j=i;j<length+i;j++) { sum+=arr[j]; if(sum>result) { result=sum; first=i; last=j; } } arr[length+i]=arr[i]; } if(last>=length) { cout<<"最大子数组起始位置为:"<<first+1<<endl; cout<<"最大子数组终止位置为:"<<last-length+1<<endl; } else { cout<<"最大子数组起始位置为:"<<first+1<<endl; cout<<"最大子数组终止位置为:"<<last+1<<endl; } cout<<"最大子数组为:"<<endl; for(int m=first;m<=last;m++) { cout<<arr[m]<<" "; } cout<<endl; cout<<"最大子数组的和为:"<<endl; cout<<result<<endl; } int main() { int num,length,first,last; first=0; last=0; cout<<"请输入数组元素个数:"; cin>>length; num=2*length; int* arr=new int[num]; cout<<"请输入数组数据:"<<endl; for(int i=0;i<length;i++) { cin>>arr[i]; } cout<<endl; Arr_Maxsum(arr,length,first,last); delete []arr; return 0; }
四、测试及截图
考虑极端情况,就是该最大连续子数组包含原数组第一个元素,测试成功
五、总结
当不考虑首尾相邻求最大连续子数组时用动态规划法是比较简单节省时间的,但是考虑数组首尾相邻时用比较简单的循环来一一求出每个最大连续子数组,时间复杂度就扩大了原来不考虑首尾相邻时间复杂度的length倍,可能有更简单的方法,对于数组长度较小时适用,当数组长度较大时这种动态规划法结合枚举法的方法时间复杂度就比较大。
六、工作合影