题目名称
Valid Sudoku—LeetCode链接
描述
Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules.
The Sudoku board could be partially filled, where empty cells are filled with the character ‘.’.
A partially filled sudoku which is valid.
Note:
A valid Sudoku board (partially filled) is not necessarily solvable. Only the filled cells need to be validated.
分析
There are just 3 rules to Sudoku.
1. Each row must have the numbers 1-9 occuring just once.
2. Each column must have the numbers 1-9 occuring just once.
3. And the numbers 1-9 must occur just once in each of the 9 sub-boxes of the grid.
C++代码
class Solution {
public:
bool isValidSudoku(vector<vector<char>>& board) {
vector<short> col(9, 0);
vector<short> block(9, 0);
vector<short> row(9, 0);
for (int i = 0; i < 9; i++)
for (int j = 0; j < 9; j++) {
if (board[i][j] != '.') {
short idx = 1 << (board[i][j] - '1');
if (row[i] & idx || col[j] & idx || block[i/3 * 3 + j / 3] & idx)
return false;
row[i] |= idx;
col[j] |= idx;
block[i/3 * 3 + j/3] |= idx;
}
}
return true;
}
};
总结
代码是别人写的,这道题我自己的方法太复杂,用了别人的一个我感觉非常好的方法,参考这里c++ very simple and easy understand. using bit operation. 用的是位操作,这也是我在编程代码中第一次看到对位的操作,所以及时翻开C++ Primer补了一下。
将数独的9*9格先按照行分成9行,存储到row中,row[0]~row[9]分别代表了第一行到第九行的值。
row[0]表示第一行,为short类型,32位机器中占两个字节,16位,初始值为0,二进制表示为:00000000 00000000。在遍历过程中,用题目描述中给定的数独举例:
1. 第一个遇到的字符为’5’,idx=1 << ‘5’-‘1’,将16位的整型1左移4位,得到16,二进制表示为:00000000 00010000;
2. 此时,判断一下row[0] & ldx,结果为0,表明在row之前没有遇到数字5;
3. 然后更新row:row[0] |= idx。
如下图所示:
这样,只需要遍历一次,就能够判断数独是否有效。