最直接的解法应该是对9*9的数组进行3次遍历,分别判断是否符合要求。下面是代码:
class Solution {
public:
bool isValidSudoku(vector<vector<char>>& board) {
int i, j;
// 先判断行是否符合要求
for (i = 0; i < 9; i++)
{
vector<int> visited(10, 0);
for (j = 0; j < 9; j++)
{
if (board[i][j] == '.')
visited[0]++;
else
{
int index = board[i][j] - '0';
visited[index]++;
}
}
if ( !isRepeated(visited) )
return false;
}
// 再判断列是否符合要求
for (j = 0; j < 9; j++)
{
vector<int> visited(10, 0);
for (i = 0; i < 9; i++)
{
if (board[i][j] == '.')
visited[0]++;
else
{
int index = board[i][j] - '0';
visited[index]++;
}
}
if ( !isRepeated(visited) )
return false;
}
// 最后判断每个3*3区域是否符合要求
for (i = 0; i <= 6; i += 3)
{
for (j = 0; j <= 6; j += 3)
{
vector<int> visited(10, 0);
for (int row = i; row <= i+2; row++)
{
for (int col = j; col <= j+2; col++)
{
if (board[row][col] == '.')
visited[0]++;
else
{
int index = board[row][col] - '0';
visited[index]++;
}
}
}
if ( !isRepeated(visited) )
return false;
}
}
return true;
}
// 判断标记数组是否合法
bool isRepeated(vector<int>& visited)
{
for (int i = 1; i <= 9; i++)
{
if (visited[i] >= 2)
return false;
}
return true;
}
};
但是仔细观察代码,只需增加额外空间,遍历的次数便能缩减到一次。这是典型的空间换时间策略。
需要做的就是开出额外的空间。