每天學習一算法系列(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找出最大值就爲該矩陣的最大子矩陣所對應的和值.

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