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,已经在注释中说到了。

最后,运行结果:

如果将注释的两个输出语句取消注释,将会得到所有情况子矩阵的信息,如下:

扫描二维码关注公众号,回复: 11176047 查看本文章

笔者能想到的解决方法暂时就是这一种,希望大家多多指教,如有问题,请评论区留言!欢迎转载收藏! 

原创文章 42 获赞 72 访问量 8226

猜你喜欢

转载自blog.csdn.net/weixin_43249548/article/details/100194730