题目:
求一个矩阵中最大的二维矩阵(元素和最大).如:
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找出最大值就为该矩阵的最大子矩阵所对应的和值.