设计思路
将二维数组转化为一位数组(并非形式上的转化而是将连续的行合并然后当做上次编写的一维数组求最大子数组和)来计算。时间复杂度没有达到要求的O(n),也是通过遍历的方式将一个子矩阵与上几个子矩阵相加如果小于0则舍去这个子矩阵,按此方法计算从这个子矩阵以后的矩阵,知道遍历完取最大值。
package soft_third_test; //20173522 李秦 public class test { static int maxSum(int p[][],int startLine,int endLine,int n){ int ans=p[endLine][1]-p[startLine][1]; int cmax=ans; for(int i=2;i<=n;i++){ int ci=p[endLine][i]-p[startLine][i]; cmax=Math.max(cmax+ci, ci); ans=Math.max(cmax, ans); } //System.out.println(startLine+" "+endLine+" "+ans); return ans; } static int[][] colSum(int arr[][]){ int m=arr.length; int n=arr[0].length; int p[][]=new int[m+1][n+1]; for(int i=1;i<=m;i++) for(int j=1;j<=n;j++) p[i][j]=p[i-1][j]+arr[i-1][j-1]; return p; } static int maxArrSum(int arr[][]){ int m=arr.length; int n=arr[0].length; if(m>n){ arr=reverseArr(arr); int tmp=m; m=n; n=tmp; } int p[][]=colSum(arr); int tempMax=0; //h表示当前矩阵的行数,即为把对多少行当做一行看待 for(int h=1;h<=m;h++) for(int i=1;i+h-1<=m;i++){ int endLine=i+h-1; //转换为长度为n的一位数著,复杂度为O(n) tempMax=Math.max(tempMax, maxSum(p,i,endLine,n)); } return tempMax; } static int[][] reverseArr(int[][] arr) { // TODO Auto-generated method stub int m=arr.length; int n=arr[0].length; int newArr[][]=new int[n][m]; for(int i=0;i<m;i++) for(int j=0;j<n;j++) newArr[j][i]=arr[i][j]; return newArr; } public static void main(String[] args) { // TODO Auto-generated method stub int arr[][]={{1,2,-51,-4,-50},{-8,-3,4,255,1},{3,8,104,1,3},{-4,-1,10,7,-6}}; int ans=maxArrSum(arr); //System.out.print("ddd"); System.out.println(ans); } }