链接:
https://leetcode.com/problems/valid-sudoku/
大意:
给定一个9x9的宫格,宫格中每个位置为'1'-'9'或者'.'。规定:
(1)对于宫格中的每一行,不能含有重复的'1'-'9'
(2)对于宫格中的每一列,不能含有重复的'1'-'9'
(3)对于宫格中的每个3x3的小宫格内(共9个小宫格),不能含有重复的'1'-'9'
称满足上述三个条件的9x9宫格为有效的数独。现需判断一个char二维数组是否为一个有效的数独
思路:
按着题目的约束,分成三步判断:
(1)检验宫格每一行是否满足要求
(2)检验宫格每一列是否满足要求
(3)检验每个小宫格是否满足要求
在我的代码中,检验行和列是否满足要求的功能,我写进了一个函数;检验每个小宫格是否满足要求,我在主函数里实现
代码:
class Solution {
public boolean isValidSudoku(char[][] b) {
// 检查行和列是否满足要求
for (int i = 0;i < 9;i++) {
if (!isValidWithRowAndCol(b, i, 0) || !isValidWithRowAndCol(b, i, 1))
return false;
}
// 检查每个3x3是否满足要求
int s = 0;
while (s < 9) {
int sRow = s / 3 * 3,eRow = sRow + 2;
int[] count = new int[10]; // 记录每个小的3x3中1-9出现的个数
while (sRow <= eRow) {
int sCol = s % 3 * 3,eCol = sCol + 2;
while (sCol <= eCol) {
if (b[sRow][sCol] != '.') {
if (count[b[sRow][sCol] - '0'] == 1)
return false;
else
count[b[sRow][sCol] - '0']++;
}
sCol++;
}
sRow++;
}
s++;
}
return true;
}
// tag = 0:行 tag = 1:列
public boolean isValidWithRowAndCol(char[][] b, int i, int tag) {
int[] count = new int[10];
if (tag == 0) {
for (int j = 0; j < 9; j++) {
if(b[i][j] != '.') {
if (count[b[i][j] - '0'] == 1)
return false;
else
count[b[i][j] - '0']++;
}
}
return true;
} else {
for (int j = 0; j < 9; j++) {
if (b[j][i] != '.') {
if (count[b[j][i] - '0'] == 1)
return false;
else
count[b[j][i] - '0']++;
}
}
return true;
}
}
}
结果:
结论:
对于这9个小宫格,推导每个小宫格对应的行和列的范围还是花了一点时间的。另外,在小宫格判定里,计数器count和列的范围sCol,eCol的放置位置出了问题,导致了几波Wrong Answer,不够细心。。。
最主要:代码感觉有点冗余(虽然感觉思路是很清晰)