- 借用计数排序思想,构建3个计数二维数组分别是行、列和九宫的计数数组,如果大于0返回false。
代码如下:
public boolean isValidSudoku(char[][] board) {
int[][] row = new int[9][9];
int[][] col = new int[9][9];
int[][] box = new int[9][9];
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
if (board[i][j] != '.') {
int num = board[i][j] - '1';
if (row[i][num] == 1 || col[j][num] == 1 || box[i / 3 * 3 + j / 3][num] == 1) {
return false;
}
row[i][num]++;
col[j][num]++;
box[i / 3 * 3 + j / 3][num]++;
}
}
}
return true;
}
其中九宫的计数数组索引计算公式:i / 3 * 3 + j / 3的意思是:九宫的一共也有九个,按行123,456,789,将1,4,7计数进1,2,3行,2,5,8计数进4,5,6,3,6,9计数进7,8,9,方便取索引。
- 官方给出了一个位运算的解法,但是位运算已经忘光了,记录一下,后面再看:
public boolean isValidSudoku(char[][] board) {
int[] line = new int[9];
int[] column = new int[9];
int[] cell = new int[9];
int shift = 0;
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
//如果还没有填数字,直接跳过
if (board[i][j] == '.')
continue;
shift = 1 << (board[i][j] - '0');
int k = (i / 3) * 3 + j / 3;
//如果对应的位置只要有一个大于0,说明有冲突,直接返回false
if ((column[i] & shift) > 0 || (line[j] & shift) > 0 || (cell[k] & shift) > 0)
return false;
column[i] |= shift;
line[j] |= shift;
cell[k] |= shift;
}
}
return true;
}