《Cracking the Coding Interview程式設計師面試金典》----最大子方塊(尋找01)

塵封的記憶0發表於2017-05-02
時間限制:3秒 空間限制:32768K 熱度指數:341
本題知識點: 程式設計基礎 陣列
 演算法知識視訊講解

題目描述

有一個方陣,其中每個單元(畫素)非黑即白(非0即1),請設計一個高效演算法,找到四條邊顏色相同的最大子方陣。

給定一個01方陣mat,同時給定方陣的邊長n,請返回最大子方陣的邊長。保證方陣邊長小於等於100。

測試樣例:
[[1,1,1],[1,0,1],[1,1,1]],3

返回:3

思路:使用動態規劃

     * left[i][j]: 座標[i,j]的左邊有連續相同的數個數,包含自己
     * above[i][j]: 座標[i,j]的上邊有連續相同的數個數,包含自己
     * 初始值:left[i][j]=1; above[i][j]=1
     * 遞推式:
     *      left[i][j]=left[i][j-1]+1,      mat[i][j]==mat[i][j-1];
     *      left[i][j]=1,                   mat[i][j]!=mat[i][j-1];
     *      above[i][j]=above[i-1][j]+1,    mat[i][j]==mat[i-1][j];
     *      above[i][j]=1,                  mat[i][j]!=mat[i-1][j];
     * 在遞推的過程中求解: mat[i][j]==mat[i][j-1]&&mat[i][j]==mat[i-1][j]

程式碼如下:

#include<iostream>
#include<vector>
using namespace std;

int maxSubMatrix(vector<vector<int> > mat, int n) {
	// write code here

	if (n == 0) return 0;
	vector<vector<int> > matA = mat;//座標點下方連續1的個數
	vector<vector<int> > matB = mat;//座標點右方連續1的個數
	vector<vector<int> > matAA = mat;//座標點下方連續0的個數
	vector<vector<int> > matBB = mat;//座標點右方連續0的個數
	int i, j;
	int len = 0;
	int wide;
	for (i = n - 1; i >= 0; --i){
		for (j = n - 1; j >= 0; --j){
			if (mat[i][j] == 0){
				matA[i][j] = 0;
				matB[i][j] = 0;
				if (i == n - 1){
					matAA[i][j] = 1;
				}
				else{
					matAA[i][j] = matAA[i + 1][j] + 1;
				}
				if (j == n - 1){
					matBB[i][j] = 1;
				}
				else{
					matBB[i][j] = matBB[i][j + 1] + 1;
				}
			}
			else {
				if (i == n - 1){
					matA[i][j] = 1;
				}
				else{
					matA[i][j] = matA[i + 1][j] + 1;
				}
				if (j == n - 1){
					matB[i][j] = 1;
				}
				else{
					matB[i][j] = matB[i][j + 1] + 1;
				}
				matAA[i][j] = 0;
				matBB[i][j] = 0;
			}
		}
	}
	for (i = 0; i<n; i++){
		for (j = 0; j<n; j++){
			if (mat[i][j] == 0){
				wide = min(matAA[i][j], matBB[i][j]);
				while (wide>0){
					if (matAA[i][j + wide - 1] >= wide && matBB[i + wide - 1][j] >= wide){
						len = len<wide ? wide : len;
					}
					wide--;
				}
			}
			else{
				wide = min(matA[i][j], matB[i][j]);
				while (wide>0){
					if (matA[i][j + wide - 1] >= wide && matB[i + wide - 1][j] >= wide){
						len = len<wide ? wide : len;
					}
					wide--;
				}
			}
		}
	}
	return len;
}

int main()
{
	vector<vector<int> > n;
	vector<int> v;
	int m;
	int temp;
	while (cin >> m)
	{
	    v.clear();
		for (int i = 0; i<m; i++)
		{
			for (int j = 0; j < m; j++)
			{
				cin >> temp;
				v.push_back(temp);
			}
			n.push_back(v);
		}
		cout<<maxSubMatrix(n, m)<<endl;
	}
	return 0;
}

不懂的可以加我的QQ群:261035036(IT程式設計師面試寶典

群) 歡迎你到來哦,看了博文給點腳印唄,謝謝啦~~


相關文章