Java算法之求某個子矩陣

 

題目

給定一個 M*N 的矩陣MATRIX,要求在此矩陣中尋找一個非空子矩陣,並使得該矩陣的和最大。

輸入

要求首先輸入兩個整數 M 和 N,分別表示矩陣的行和列,再在接下來依次輸入矩陣的值MATRIX[I][J]

樣例:

3 3
2 -4 1
-1 2 1
4 -2 2

輸出

輸出一行,包含一個整數,表示 MATRIX中最大子矩陣的元素和

樣例:

6

分析

當看到這道題時,腦子裏首先是怎麼尋找子矩陣,並且要把所有的子矩陣都找一遍。到這裏想了想以前學過的線性代數,似乎沒想起什麼辦法尋找子矩陣。對於一個矩陣來說,其子矩陣實在太多了,我們需要找到一個合適的辦法來挨個找它的子矩陣。那麼我們怎麼找,還是這個問題,規律在哪?因此我們需要自己在本子或者其他地方做一些草稿,在這個過程中,我們會發現矩陣他有一個特點:它的形狀是一個矩形(這不廢話嗎)...但是對於矩形,我們可是知道的,我們只要通過一組對角的座標就能確定這個矩形的位置。因此拿到矩陣裏來也是一樣的,我們只要兩個座標點就能確定一個子矩陣。那麼這就很好辦了。我們只需要挨着把所有座標點都訪問一遍就行了。

package 計蒜客;
import java.util.Scanner;
public class Matrix {

	public static void main(String[] args) 
	{
		Scanner sc=new Scanner(System.in);
		int row=sc.nextInt();
		int colum=sc.nextInt();
		int[][] matrix=new int[row][colum];
		/*
		 * 輸入矩陣的值
		 */
		for(int i=0;i<row;i++)
		{
			for(int j=0;j<colum;j++)
			{
				matrix[i][j]=sc.nextInt();
			}
		}
		/*
		 * 定義變量valueTMP用來就算矩陣元素和,
		 valueMAX用來保存最大值
		  */
		int valueTMP=0;
		int valueMAX=matrix[0][0];
		/*
		 * 六層循環,第一二層確定矩陣的第一個座標
		 * 第三四層確定矩陣的第二個座標
		 * 第五六層把兩個座標點確定的矩陣的元素求和,其實也就是遍歷了一遍
		 * */
		for(int a=0;a<row;a++)
		{
			for(int b=0;b<colum;b++)
			{
				for(int a1=a;a1<row;a1++)
				{
					for(int b1=b;b1<colum;b1++)
					{
//						System.out.print("start:"+a+","+b+"^^^^^^");
//						System.out.println("end:"+a1+","+b1);
						for(int r=a;r<=a1;r++)
						{
							for(int c=b;c<=b1;c++)
							{							
								valueTMP+=matrix[r][c];
							}
						}
						if(valueTMP>valueMAX)
						{
							valueMAX=valueTMP;
						}
                        //每次用完之後,都要把valueTMP置0
						valueTMP=0;
					}
				}
			}
		}
		System.out.println(valueMAX);
	}
}

。這裏有幾個細節需要看一下,第一個就是valueMAX的初始值問題,賦值爲矩陣第一個元素,而不是0,考慮一種極端情況,若所有元素都爲負數,0的話將會輸出錯誤結果。第二,循環的三四層,也就是確定另一個座標,我們要從上一個座標開始,而不是上一個座標的下一個開始,這裏我們考慮另一種極限情況,子矩陣只有一個元素。第三,也就是valueTMP,已經在註釋中說到了。

最後,運行結果:

如果將註釋的兩個輸出語句取消註釋,將會得到所有情況子矩陣的信息,如下:

筆者能想到的解決方法暫時就是這一種,希望大家多多指教,如有問題,請評論區留言!歡迎轉載收藏! 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章