LeetCode840:矩阵中的幻方

3 x 3 的幻方是一个填充有从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。

给定一个由整数组成的 N × N 矩阵,其中有多少个 3 × 3 的 “幻方” 子矩阵?(每个子矩阵都是连续的)。

示例 1:

输入: [[4,3,8,4],
      [9,5,1,9],
      [2,7,6,2]]
输出: 1
解释: 
下面的子矩阵是一个 3 x 3 的幻方:
438
951
276

而这一个不是:
384
519
762

总的来说,在本示例所给定的矩阵中只有一个 3 x 3 的幻方子矩阵。

提示:

  1. 1 <= grid.length = grid[0].length <= 10
  2. 0 <= grid[i][j] <= 15

解析:

        该题目,主要分为两个步骤,一个是将原矩阵,划分为若干个3*3的矩阵,第二步是判断3*3的矩阵是否是幻阵。在划分的时候注意矩阵是否可划分,即行列是否都大于等于3,还要注意最后一个划分起点的位置。判断幻阵时,注意是否有重复元素和大于9的元素,然后只需要判断第一行,第一列,第一个对角线和第二行,第二列即可,不需要所有行列对角线都判断,因为这5个已经涵盖了所有元素。

代码:

//判断是否幻阵
bool isMagicSquares(vector<vector<int>>& subGrid)
{
	set<int>sGrid;
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 3; j++)
		{
			sGrid.insert(sGrid.begin(), subGrid[i][j]);
		}
	}
//用set判断是否有重复元素和大于9的元素
	if (sGrid.size() < 9 || *(--sGrid.end()) > 9)
		return false;
	if (subGrid[0][0] + subGrid[0][1] + subGrid[0][2] != 15)
		return false;
	if (subGrid[0][0] + subGrid[1][1] + subGrid[2][2] != 15)
		return false;
	if (subGrid[0][0] + subGrid[1][0] + subGrid[2][0] != 15)
		return false;
	if (subGrid[1][0] + subGrid[1][1] + subGrid[1][2] != 15)
		return false;
	return true;
}

int numMagicSquaresInside(vector<vector<int>>& grid) 
{
	vector<vector<int>>subGrid(3,vector<int>(3));
	int rows = grid.size();
	int cols = grid[0].size();
	if (rows < 3 || cols < 3)
		return 0;
	int res = 0;
	for (int i = 0; i < rows - 2; i++)
	{
		for (int j = 0; j < cols - 2; j++)
		{
			subGrid[0][0] = grid[i][j];
			subGrid[0][1] = grid[i][j+1];
			subGrid[0][2] = grid[i][j+2];
			subGrid[1][0] = grid[i+1][j];
			subGrid[1][1] = grid[i+1][j+1];
			subGrid[1][2] = grid[i+1][j+2];
			subGrid[2][0] = grid[i+2][j];
			subGrid[2][1] = grid[i+2][j+1];
			subGrid[2][2] = grid[i+2][j+2];
			if (isMagicSquares(subGrid))
				res++;
		}
	}
	return res;
}

猜你喜欢

转载自blog.csdn.net/qq_36214481/article/details/86536020