一、题目要求
题目:返回一个二维整数数组中最大子数组的和。
要求:
输入一个二维整形数组,数组里有正数也有负数。
二维数组首尾相接,象个一条首尾相接带子一样。
数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。
求所有子数组的和的最大值。要求时间复杂度为O(n)。
二、设计思路
先调用以前求二维最大连续子数组之和的maxSubArray函数求一个首尾不相邻的二维最大连续子数组之和,接着用将第k列各元素左移一列可以再求一个最大连续子数组之和 ,循环m次(因为原二维数组有m列)求得每个最大值保存在arr一维数组中,最后求arr数组最大值就是题目所求二维数组最大连续子数组之和。
三、代码
#include <iostream.h> int maxSubArray(int **a,int n,int m) { int **p=new int*[n]; int i,j; if(m==0||n==0) return 0; //计算p[i][j] for(i=0;i<n;i++) { p[i]=new int[m]; for(j=0;j<m;j++) { if(i==0) { if(j==0) p[i][j]=a[i][j]; else p[i][j]=p[i][j-1]+a[i][j]; } else { if(j==0) p[i][j]=p[i-1][j]+a[i][j]; else p[i][j]=p[i][j-1]+p[i-1][j]-p[i-1][j-1]+a[i][j]; } } } //计算二维数组最大子数组的和 int temp; int max=a[0][0]; int sum; //如果m==1 if(m==1) { for(i=0;i<n;i++) { for(j=i;j<n;j++) { if(i==0) { temp=p[j][m-1]; } else { temp=p[j][m-1]-p[i-1][m-1]; } if(sum<temp) sum=temp; } } } else { for(i=0;i<n;i++) { for(j=i;j<n;j++) { if(i==0) { temp=p[j][m-1]-p[j][m-2]; } else { temp=p[j][m-1]-p[j][m-2]-p[i-1][m-1]+p[i-1][m-2]; } for(int k=m-2;k>=0;k--) { if(temp<0) temp=0; if(i==0) { if(k==0) temp+=p[j][k]; else temp+=p[j][k]-p[j][k-1]; } else { if(k==0) temp+=p[j][k]-p[i-1][k]; else temp+=p[j][k]-p[j][k-1]-p[i-1][k]+p[i-1][k-1]; } if(sum<temp) sum=temp; } } } } return sum; } int main() { int n,m; int max; cout<<"请输入二维数组的行数:"<<endl; cin>>n; cout<<"请输入二维数组的列数"<<endl; cin>>m; int i,j; int **a=new int*[n]; int *arr=new int[m]; cout<<"请输入该二维数组元素:"<<endl; for(i=0;i<n;i++) { a[i]=new int[m]; for(j=0;j<m;j++) { cin>>a[i][j]; } } for(i=0;i<m;i++) { arr[i]=maxSubArray(a,n,m); for(int k=0;k<n;k++) { for(j=0;j<m;j++) { a[k][(j+1)%m]=a[k][j]; }//循环将k列的元素左移一列 } } for(i=0;i<m;i++) { max=arr[0]; if(max<arr[i]) { max=arr[i]; } } cout<<"二维数组的最大连续子数组之和:"<<max<<endl; return 0; }
四、测试截图
五、总结
我感觉思路没错但是实现时有错误,我试图找出代码中错误所在,就将主函数改了输出每个最大子数组之和结果出现下图结果
所以我想估计是这部分代码有问题
for(i=0;i<m;i++) { arr[i]=maxSubArray(a,n,m); for(int k=0;k<n;k++) { for(j=0;j<m;j++) { a[k][(j+1)%m]=a[k][j]; }//循环将k列的元素左移一列 } }
但是我感觉逻辑思路上很heli(醉了,打出这两个字就出现下图),不知道错在哪里,弄了好久,纠结中!
六、工作合影