1. 程式人生 > >最大方子陣與最大和子矩陣--Java語言

最大方子陣與最大和子矩陣--Java語言

本文主要講的是關於矩陣的子方陣問題,典型題型有:所有元素為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