36. Valid Sudoku

Posted panini

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了36. 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 ‘.‘.

技术分享

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.

链接: http://leetcode.com/problems/valid-sudoku/

一刷,此题目的意思是只要单纯检查输入是不是满足行列和组里没有重复数字,不关心是否能够解出。一遍loop,重点在于找到在第几组里,写出行列号就可以找到。

class Solution(object):
    def isValidSudoku(self, board):
        """
        :type board: List[List[str]]
        :rtype: bool
        """
        rsets = [set() for i in range(9)]
        csets = [set() for i in range(9)]
        gsets = [set() for i in range(9)]
        
        for idx in range(81):
            r = idx / 9
            c = idx % 9
            g = r / 3 * 3 + c / 3
            value = board[r][c]
            if value == .:
                continue
            if value in rsets[r] or value in csets[c] or value in gsets[g]:
                return False
            rsets[r].add(value)
            csets[c].add(value)
            gsets[g].add(value)
        return True

上面方法用了9个set,太多,并且因为降为一维很多特征并不容易找到。

参考别人方法。这个方法只有一次内外循环检查三个特征:1) 外循环行,内循环列,2) 外循环列,内循环行, 3) 外循环大组,内循环组里的9个元素。因为都是3*3方形矩阵,所以取巧用一次循环。

class Solution(object):
    def isValidSudoku(self, board):
        rset = set()
        cset = set()
        gset = set()
        for row in range(len(board)):
            for col in range(len(board[0])):
                if board[row][col] != . and board[row][col] in rset:
                    return False
                if board[col][row] != . and board[col][row] in cset:
                    return False
                grow = row / 3 * 3
                gcol = row % 3 * 3
                if board[grow + col / 3][gcol + col % 3] != . and board[grow + col / 3][gcol + col % 3] in gset:
                    return False
                rset.add(board[row][col])
                cset.add(board[col][row])
                gset.add(board[grow + col / 3][gcol + col % 3])
            rset = set()
            cset = set()
            gset = set()
        return True

其他人的python解法:https://leetcode.com/discuss/48737/1-7-lines-python-4-solutions

def isValidSudoku(self, board):
    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))

这个方法来检查immutable的tuple个数,c元素在行列和组中的位置和值组成的三种tuple分别是

(row_index, str), (str, col_index), (row_index, col_index, str),其中str类型为string。先把所有元素的这三种tuple加入一个list中,然后和由list组成的set比较长度,如果长度不一致,必然是因为list中有重复元素,因为数独输入不合法。

 

以上是关于36. Valid Sudoku的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode-36. Valid Sudoku

[LeetCode] 36. Valid Sudoku

[leetcode-36-Valid Sudoku]

leetcode36. Valid Sudoku

36. Valid Sudoku

36. Valid Sudoku