LeetCode算法题36:有效的数独解析

判断一个 9x9 的数独是否有效。只需要根据以下规则,验证已经填入的数字是否有效即可。

  1. 数字 1-9 在每一行只能出现一次。
  2. 数字 1-9 在每一列只能出现一次。
  3. 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。
    在这里插入图片描述
    上图是一个部分填充的有效的数独。

数独部分空格内已填入了数字,空白格用 ‘.’ 表示。
示例 1:

输入:
[
  ["5","3",".",".","7",".",".",".","."],
  ["6",".",".","1","9","5",".",".","."],
  [".","9","8",".",".",".",".","6","."],
  ["8",".",".",".","6",".",".",".","3"],
  ["4",".",".","8",".","3",".",".","1"],
  ["7",".",".",".","2",".",".",".","6"],
  [".","6",".",".",".",".","2","8","."],
  [".",".",".","4","1","9",".",".","5"],
  [".",".",".",".","8",".",".","7","9"]
]
输出: true

示例 2:

输入:
[
  ["8","3",".",".","7",".",".",".","."],
  ["6",".",".","1","9","5",".",".","."],
  [".","9","8",".",".",".",".","6","."],
  ["8",".",".",".","6",".",".",".","3"],
  ["4",".",".","8",".","3",".",".","1"],
  ["7",".",".",".","2",".",".",".","6"],
  [".","6",".",".",".",".","2","8","."],
  [".",".",".","4","1","9",".",".","5"],
  [".",".",".",".","8",".",".","7","9"]
]
输出: false
解释: 除了第一行的第一个数字从 5 改为 8 以外,空格内其他数字均与 示例1 相同。
     但由于位于左上角的 3x3 宫内有两个 8 存在, 因此这个数独是无效的。

说明:

  • 一个有效的数独(部分已被填充)不一定是可解的。
  • 只需要根据以上规则,验证已经填入的数字是否有效即可。
  • 给定数独序列只包含数字 1-9 和字符 ‘.’ 。
  • 给定数独永远是 9x9 形式的。

这个题就按标记查看行、列、3*3单元格是否数字重复即可,遍历整个表时遇到数字将对应标志数组的位置置为true,如果下次发现位置已经为true说明重复,返回false。行列的标志很好置位,单元格的数组置位可以这样:一共九个单元格,其坐标与数组对应位置为

(0,0)(0,1)(0,2)			(0,3)(0,4)(0,5)			(0,6)(0,7)(0,8)
(1,0)(1,1)(1,2)-->第0行	(1,3)(1,4)(1,5)-->第1行	(1,6)(1,7)(1,8)-->第2行
(2,0)(2,1)(2,2)			(2,3)(2,4)(2,5)			(2,6)(2,7)(2,8)
(3,0)(3,1)(3,2)			(3,3)(3,4)(3,5)			(3,6)(3,7)(3,8)
(4,0)(4,1)(4,2)-->第3行	(4,3)(4,4)(4,5)-->第4行	(4,6)(4,7)(4,8)-->第5行
(5,0)(5,1)(5,2)			(5,3)(5,4)(5,5)			(5,6)(5,7)(5,8)
(6,0)(6,1)(6,2)			(6,3)(6,4)(6,5)			(6,6)(6,7)(6,8)
(7,0)(7,1)(7,2)-->第8行	(7,3)(7,4)(7,5)-->第7行	(7,6)(7,7)(7,8)-->第8行
(8,0)(8,1)(8,2)			(8,3)(8,4)(8,5)			(8,6)(8,7)(8,8)

所以其对应关系可以描述为3*(i/3)+(j/3)。

C++源代码:

class Solution {
public:
    bool isValidSudoku(vector<vector<char>>& board) {
        int m = board.size();
        int n = board[0].size();
        if (m!=9 || n!=9) return false;
        vector<vector<bool>> row(m, vector<bool>(n, false));
        vector<vector<bool>> col(m, vector<bool>(n, false));
        vector<vector<bool>> cell(m, vector<bool>(n, false));
        for(int i=0;i<m;i++)
        {
            for(int j=0;j<n;j++)
            {
                int t = board[i][j];
                if(t>='1' && t<='9')
                {
                    int k = t - '1';
                    if(row[i][k] || col[k][j] || cell[3*(i/3)+j/3][k])
                        return false;
                    row[i][k] = true;
                    col[k][j] = true;
                    cell[3*(i/3)+j/3][k] = true;
                }
            }
        }
        return true;
    }
};

python3源代码:

class Solution:
    def isValidSudoku(self, board):
        """
        :type board: List[List[str]]
        :rtype: bool
        """
        m = len(board)
        n = len(board[0])
        if m!=9 or n!=9:
            return False
        row = [[False for col in range(n)] for row in range(m)]
        col = [[False for col in range(n)] for row in range(m)]
        cell = [[False for col in range(n)] for row in range(m)]
        for i in range(m):
            for j in range(n):
                t = ord(board[i][j])
                if t>=ord('1') and t<=ord('9'):
                    k = t - ord('1')
                    if row[i][k] or col[k][j] or cell[3*(i//3)+(j//3)][k]:
                        return False
                    row[i][k] = True
                    col[k][j] = True
                    cell[3*(i//3)+(j//3)][k] = True
        return True

这里要注意的是python中list初始化的时候的代码,这种初始化是比较推荐的,如果使用[[false]*n]*m这种方式只是浅复制,会造成只要修改一个那么每一行都会修改的问题。所以还是采用推荐的方法去初始化列表。

猜你喜欢

转载自blog.csdn.net/x603560617/article/details/84873723