最大方子陣與最大和子矩陣--Java語言
阿新 • • 發佈:2019-02-11
本文主要講的是關於矩陣的子方陣問題,典型題型有:所有元素為1的最大子方陣、最大和子矩陣。
首先先講述的是所有元素為1的最大子方陣。可以利用動態規劃方法求解該問題。用B[m][n]表示二元矩陣。演算法的思想是構造一個臨時矩陣res[][],其中res[i][j]表示包括B[i][j]在內的值全為1的子方陣的大小,B[i][j]是該子方陣最右下角的元素。因此,初始時,res第一行與第一列的值即為B矩陣第一行與第一列的值。然後遍歷B[i][j],判斷B[i][j],如果B[i][j]=0,則res[i][j]=0,否則res[i][j]的值跟res[i-1][j-1]、res[i-1][j]、res[i][j-1]有關,取三者最小值加1.
程式碼實現:
import java.util.*; public class MatrixWithAllOnes { public static void matrixWithAllOnes(int[][]B,int m,int n) { int[][] res=new int[m][n]; int max_of_s,max_i,max_j; for(int i=0;i<m;i++) res[i][0]=B[i][0]; for(int j=0;j<n;j++) res[0][j]=B[0][j]; for(int i=1;i<m;i++) { for(int j=1;j<n;j++) { if(B[i][j]==1) res[i][j]=Math.min(res[i][j-1], Math.min(res[i-1][j-1], res[i-1][j]))+1;//取三者最小值,為了保證是方陣。 else res[i][j]=0; } } max_of_s=res[0][0]; max_i=0; max_j=0; for(int i=0;i<m;i++) { for(int j=0;j<n;j++) { if(res[i][j]>max_of_s) { max_of_s=res[i][j]; max_i=i; max_j=j; } } } System.out.println("Maximum sub-matrix"); for(int i=max_i-max_of_s+1;i<=max_i;i++) { for(int j=max_j-max_of_s+1;j<=max_j;j++) System.out.print(B[i][j]+" "); System.out.println(); } System.out.println("所有元素為1的最大子方陣的大小:"); System.out.println(max_of_s+"x"+max_of_s); } public static void main(String[] args) { // TODO Auto-generated method stub Scanner sc=new Scanner(System.in); System.out.println("輸入矩陣大小:"); String[] str=sc.nextLine().split(" "); int m=Integer.parseInt(str[0]); int n=Integer.parseInt(str[1]); int[][] B=new int[m][n]; int k=0; System.out.println("輸入原矩陣:"); while(k<m&&sc.hasNextLine()) { String[] str1=sc.nextLine().split(" "); for(int i=0;i<str1.length;i++) B[k][i]=Integer.parseInt(str1[i]); k++; } System.out.println("所有元素為1的最大子方陣:"); matrixWithAllOnes(B,m,n); } }
測試結果:
輸入矩陣大小:
6 5
輸入原矩陣:
0 1 1 0 1
1 1 0 1 0
0 1 1 1 0
1 1 1 1 0
1 1 1 1 1
0 0 0 0 0
所有元素為1的最大子方陣:
Maximum sub-matrix
1 1 1
1 1 1
1 1 1
所有元素為1的最大子方陣的大小:
3x3
接著講述關於最大和子矩陣的問題。程式碼實現:
public class FindMaximumSubMatrix { public static void findMaximumSubMatrix(int[][] A,int n) { int[][] M=new int[n][n]; for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { if(j==0) M[j][i]=A[j][i]; else M[j][i]=A[j][i]+M[j-1][i]; } } int maxSoFar=0; int min,subMatrix; for(int i=0;i<n;i++) { for(int j=i;j<n;j++) { min=0; subMatrix=0; for(int k=0;k<n;k++) { if(i==0) subMatrix+=M[j][k]; else subMatrix+=M[j][k]-M[i-1][k]; if(subMatrix<min) min=subMatrix; if((subMatrix-min)>maxSoFar) { maxSoFar=subMatrix-min; } } } } System.out.println(maxSoFar); } public static void main(String[] args) { // TODO Auto-generated method stub int[][] A= {{0,-2,-7,0},{9,2,-6,2},{-4,1,-4,1},{-1,8,0,-2}}; int n=A.length; findMaximumSubMatrix(A,n); } }
測試結果:
15