36. Valid Sudoku [easy] (Python)

题目链接

https://leetcode.com/problems/valid-sudoku/

题目原文

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 ‘.’.
36. Valid Sudoku [easy] (Python)_第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.

题目翻译

判断一个数独是否是有效的。判断依据:Sudoku Puzzles - The Rules。
一个数独的表格可以是只填写了一部分,空的格子用点号’.’填充,比如,下图是一个有效的部分数独:
36. Valid Sudoku [easy] (Python)_第2张图片
注意:一个有效的数独板(部分填充的)不一定可解。你只需要验证被填充的部分即可。

思路方法

首先,简单说一下规则:数独的每一行、每一列、9个九宫格里的数字只能是0-9,且不能重复。

思路一

最直观的思路,三个规则全部检查一遍即可。

代码

class Solution(object):
    def isValidSudoku(self, board):
        """
        :type board: List[List[str]]
        :rtype: bool
        """
        for i in range(9):
            if not self.isValidNine(board[i]):
                return False
            col = [c[i] for c in board]
            if not self.isValidNine(col):
                return False
        for i in [0, 3, 6]:
            for j in [0, 3, 6]:
                block = [board[s][t] for s in [i, i+1, i+2] for t in [j, j+1, j+2]]
                if not self.isValidNine(block):
                    return False
        return True

    def isValidNine(self, row):
        map = {}
        for c in row:
            if c != '.':
                if c in map:
                    return False
                else:
                    map[c] = True
        return True

思路二

上面的代码虽然很好理解,但很冗余。我们可以用三个矩阵分别检查三个规则是否有重复数字,比如用row, col, block分别检查行、列、块是否有重复数字,代码如下:

代码

class Solution(object):
    def isValidSudoku(self, board):
        """
        :type board: List[List[str]]
        :rtype: bool
        """
        # 注意:这里不能用[[False]*9]*9来初始化,牵涉到深浅拷贝的问题
        row = [[False for i in range(9)] for j in range(9)]
        col = [[False for i in range(9)] for j in range(9)]
        block = [[False for i in range(9)] for j in range(9)]
        for i in range(9):
            for j in range(9):
                if board[i][j] != '.':
                    num = int(board[i][j]) - 1
                    k = i/3*3 + j/3
                    if row[i][num] or col[j][num] or block[k][num]:
                        return False
                    row[i][num] = col[j][num] = block[k][num] = True
        return True

思路三

类似思路二,可以记录所有出现过的行、列、块的数字及相应位置,最后判断是否有重复。用set操作精简代码,可以有如下实现:

代码

class Solution(object):
    def isValidSudoku(self, board):
        """
        :type board: List[List[str]]
        :rtype: bool
        """
        seen = []
        for i, row in enumerate(board):
            for j, c in enumerate(row):
                if c != '.':
                    seen += [(c,j),(i,c),(i/3,j/3,c)]
        return len(seen) == len(set(seen))

PS: 新手刷LeetCode,新手写博客,写错了或者写的不清楚还请帮忙指出,谢谢!
转载请注明:http://blog.csdn.net/coder_orz/article/details/51596499

你可能感兴趣的:(LeetCode,LeetCode解题报告)