Valid Sudoku

题目名称
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 ‘.’.

Valid Sudoku_第1张图片

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。
如下图所示:
Valid Sudoku_第2张图片

  这样,只需要遍历一次,就能够判断数独是否有效。

你可能感兴趣的:(LeetCode,sudoku,数独)