每天学习一算法系列(32)(求一个矩阵中最大的二维矩阵(元素和最大))

 题目:

求一个矩阵中最大的二维矩阵(元素和最大).如:
1 2 0 3 4
2 3 4 5 1
1 1 5 3 0
中最大的二维矩阵是:
4 5
5 3

要求:(1)写出算法;(2)分析时间复杂度;(3)用C 写出关键代码.

 

思路一:
这个题目要求出最大的二维矩阵,我们首先想到的一个解法就是:从行1到行N进行遍历,以二维矩阵为单元进行遍历,也就说(行x列x -- 行x+1列x+1)为一个单位进行遍历,遍历的过程中记录该矩阵的和值,并和最大和值进行比较,保存最大的二维矩阵和值所对应的行列值,直到遍历结束就可以找到最大的二维矩阵。O(NLine*NCol),其中NLine代表的是该矩阵的行数,NCol代表的该矩阵的列数。

 

代码如下:

/*-----------------------------
Copyright by yuucyf. 2011.08.25
------------------------------*/

#include "stdafx.h"
#include <assert.h>
#include <iostream>
using namespace std;

typedef struct tagMatrixInfo
{
	int i32nLine;
	int i32nCol;
	
	tagMatrixInfo()
	{
		i32nLine = i32nCol = 0;
	}
}S_MatrixInfo;


S_MatrixInfo GetMax2X2Matrix(int **ppMatrix, int nLine, int nCol)
{
	assert(ppMatrix);
	assert(nLine >= 2);
	assert(nCol >= 2);

	S_MatrixInfo sMaxMatrixInfo;

	int nMaxValue = 0, nTempValue = 0;
	for (int i32I = 0; i32I < nLine - 1; i32I++)
	{
		for (int i32J = 0; i32J < nCol - 1; i32J++)
		{
			nTempValue += (ppMatrix[i32I][i32J] + ppMatrix[i32I][i32J+1]); 
			nTempValue += (ppMatrix[i32I+1][i32J] + ppMatrix[i32I+1][i32J+1]);

			if (nTempValue > nMaxValue)
			{
				nMaxValue = nTempValue;
				sMaxMatrixInfo.i32nLine = i32I;
				sMaxMatrixInfo.i32nCol  = i32J;
			}
			nTempValue = 0;
		}
	}

	return sMaxMatrixInfo;
}


int _tmain(int argc, _TCHAR* argv[])
{
	int i32I = 0, i32J = 0;
	int i32nLine = 0, i32nCol = 0;
	cin >> i32nLine >> i32nCol;
	int **ppMatrix = new int *[i32nLine];
	assert(ppMatrix);

	for (i32I = 0; i32I < i32nLine; i32I++)
	{
		ppMatrix[i32I] = new int[i32nCol];
		assert(ppMatrix[i32I]);

		for (i32J = 0; i32J < i32nCol; i32J++)
		{
			cin >> ppMatrix[i32I][i32J];
		}
	}

	S_MatrixInfo sMaxMatrixInfo = GetMax2X2Matrix(ppMatrix, i32nLine, i32nCol);
	cout << endl << "最大的二维矩阵为:" << endl;
	for (i32I = sMaxMatrixInfo.i32nLine; i32I < sMaxMatrixInfo.i32nLine + 2; i32I++)
	{
		for (i32J = sMaxMatrixInfo.i32nCol; i32J < sMaxMatrixInfo.i32nCol + 2; i32J++)
		{
			cout << ppMatrix[i32I][i32J] << " ";
		}
		cout << endl;
	}

         return 0;
}


扩展:
如果题目是要求求最大的子矩阵呢,那么我们就可以把矩阵每一竖直方向的排列,看做一个元素。
所以,矩阵就转化成了我们熟悉的一维数组。
即以上矩阵,相当于:
a[1->n][1] a[1->n][2] ... a[1->n][i] .. a[1->n][j] .. a[1->n][n]
1->n 表示竖直方向,其中a[1->n][1]表示第一列中的所有元素相加后的值。
那么,
假定是5X5矩阵,那解法是:
第一行:a[1-5][1]  a[1-5][2]  a[1-5][3] a[1-5][4] a[1-5][5] 形成一个一维数组,该数组的最大和值为Sum1.

第二行:a[2-5][1]  a[2-5][2]  a[2-5][3] a[2-5][4] a[2-5][5] 形成一个一维数组,该数组的最大和值为Sum2.

第三行:a[3-5][1]  a[3-5][2]  a[3-5][3] a[3-5][4] a[3-5][5] 形成一个一维数组,该数组的最大和值为Sum3.

第四行:a[4-5][1]  a[4-5][2]  a[4-5][3] a[4-5][4] a[4-5][5] 形成一个一维数组,该数组的最大和值为Sum4.

第五行:a[5][1]  a[5][2]  a[5][3] a[5][4] a[5][5] 形成一个一维数组,该数组的最大和值为Sum5.

然后比较Sum1到Sum5找出最大值就为该矩阵的最大子矩阵所对应的和值.

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