1.O(N*N*M*M)通过遍历每个矩形,来获取最大矩形和。(用一个二维数组保存从顶点到目标点之间的矩形和)
import java.util.*; public class Test{ public static void main(String[] args) { int[][] nums={{2,1,-3,-4,5},{0,6,3,4,1},{2,-2,-1,4,-5},{-3,3,1,0,3}}; int len1=nums.length; int len2=nums[0].length; int[][] dp=new int[len1+1][len2+1]; dp[0][0]=0; for(int i=0;i<=len1;i++){ dp[i][0]=0; } for(int i=0;i<=len2;i++){ dp[0][i]=0; } for(int i=1;i<=len1;i++){ for(int j=1;j<=len2;j++){ dp[i][j]=dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1]+nums[i-1][j-1]; } } int max=nums[0][0]; for(int xmin=1;xmin<=len1;xmin++){ for(int xmax=xmin;xmax<=len1;xmax++){ for(int ymin=1;ymin<len2;ymin++){ for(int ymax=ymin;ymax<=len2;ymax++){ max=Math.max(max,dp[xmax][ymax]+dp[xmin-1][ymin-1]-dp[xmin-1][ymax]-dp[xmax][ymin-1]); } } } } System.out.println(max); } }
2.O(N*N*M)将首尾行固定住,然后像一位子数组和那样求二维最大子数组和
import java.util.*; public class Main{ public static void main(String[] args) { int[][] nums={{2,1,-3,-4,5},{0,6,3,4,1},{2,-2,-1,4,-5},{-3,3,1,0,3}}; int len1=nums.length; int len2=nums[0].length; int max=nums[0][0]; for(int xmin=0;xmin<len1;xmin++){ for(int xmax=xmin;xmax<len1;xmax++){ int[] colsSum=new int[len2]; for(int i=0;i<len2;i++){ for(int j=xmin;j<=xmax;j++){ colsSum[i]+=nums[j][i]; } } int tempMax=colsSum[0]; int tempSum=colsSum[0]; for(int i=1;i<len2;i++){ if(tempSum<0){ tempSum=0; } tempSum+=colsSum[i]; tempMax=Math.max(tempMax,tempSum); } max=Math.max(max,tempMax); } } System.out.println(max); } }