题目:
方法:
首先思路一定要清晰,我们的任务目标是:
- 判断每一行的重复
- 判断每一列
- 判断3*3的子矩阵
思路:首先明确需要计数,可以使用哈希表,这里就是1-9数字,可以使用数组来解决。如何有效提高效率呢?一次遍历,三任务同时进行:
①双for循环遍历所有元素,不为空的进行任务判断
②对于整个数独9*9模板,有9行,9列,和9个子矩阵:
- 对于i行,row[i][index]进行计数
- 对于j列,cow[j][index]进行计数
- 对于子矩阵,巧妙利用除法取整的性质bBox[i/3][j/3][index]进行计数
其中注意index = board[i][j]-'0'-1;
- 首先board[i][j]是char字符型,其存储值为对应的ascii码,而这些ascii码是连续的,且按照其本身数字的大小来排列。
- 这样就可以将字符值,减去起始ascii码值
-‘0’
实现转为对应值的效果。 - 最后的
-1
是因为使用数组计数时,我们用索引0-8对应数字1-9
最后与官方解法的对比:
我的速度略胜一筹,内存消耗略逊一筹,我们的不同点在于:
- 初始化:官方使用了memset函数,这里我直接用的
{0}
全部为0
int rows[9][9];
int columns[9][9];
int subboxes[3][3][9];
memset(rows,0,sizeof(rows));
memset(columns,0,sizeof(columns));
memset(subboxes,0,sizeof(subboxes));
- 在判断为数字时,官方先赋值给了char再判断,感觉效率不高:
char c = board[i][j];
if (c != '.')
- 最后在if判断中,我判断的是
==2
,官方是>1
,个人认为还是=2比较好,因为直接判断相等逻辑更严格,可以防止意想不到的错误。此外判断可能更快一点(目前测试的效果是这样)因为相等的话按位只要有一个不符合就直接不等了。
class Solution {
public:
bool isValidSudoku(vector<vector<char>>& board) {
int row[9][9]{0};
int cow[9][9]{0};
int bBox[3][3][9]{0};
int index(0);
for (int i=0; i<9; i++){
for(int j=0; j<9; j++){
if (board[i][j] != '.'){
index = board[i][j]-'0'-1;
row[i][index]++;
cow[j][index]++;
bBox[i/3][j/3][index]++;
if (row[i][index]==2 || cow[j][index]==2 || bBox[i/3][j/3][index]==2)
return false;
}
}
}
return true;
}
};