[PythonのLeetCode] 36(M)有効な数独

タイトル

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

9x9の数独が有効かどうかを判断します。入力した番号が以下のルールに従って有効かどうかを確認するだけで済みます。

1から9までの数字は、1行に1回しか表示できません。
1〜9の数字は、各列に1回だけ表示できます。
1〜9の数字は、太い実線で区切られた各3x3の家に1回だけ表示されます。

上の写真は部分的に塗りつぶされた効果的な数独です。

数独部分のスペースは数字で埋められており、空白スペースは「。」で示されています。

例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の宮殿には2つの8があるので、この数独は無効です。

説明:

有効な数独(部分的に埋められている)は必ずしも解決可能ではありません。
入力した番号が上記のルールに従って有効かどうかを確認するだけです。
指定された数独シーケンスには、1〜9の数字と文字「。」のみが含まれています。
特定の数独は常に9x9の形式です。

問題解決のアイデア

  • ナイーブの考え方は、行、列、および9つのグリッドで個別に検証することであり、ループの数は3 9 * 9です。

  • 以下のコードを参照してくださいnaive version

  • 観察後、行、列、および9グリッドグリッドに表示された数値は、実際にはコレクションを通じて格納できるため、9 * 9サイクルのみが必要であることがわかります。

  • 以下のコードを参照してくださいoptimized version

  • さらに、set()を使用しない、代わりに配列を使用する、ストレージにビットを使用するなど、他の最適化方法もあります。

コード

# - naive version

class Solution:
    def isValidSudoku(self, board: List[List[str]]) -> bool:
        # - check for each row
        for row in range(9):
            exist_set = set()
            for col in range(9):
                c = board[row][col]
                if c == '.': continue

                if c in exist_set:
                    return False
                else:
                    exist_set.add(c)
        
        # - check for each col
        for col in range(9):
            exist_set = set()
            for row in range(9):
                c = board[row][col]
                if c == '.': continue

                if c in exist_set:
                    return False
                else:
                    exist_set.add(c)
        
        # - check for each grid
        for gr in range(3):
            for gc in range(3):
                exist_set = set()

                for j in range(3):
                    for i in range(3):
                        c = board[gr*3 + j][gc*3 + i]
                        if c == '.': continue

                        if c in exist_set:
                            return False
                        else:
                            exist_set.add(c)
        
        return True
# - optimized version

class Solution:
    def isValidSudoku(self, board: List[List[str]]) -> bool:
        row_state_list = [set() for _ in range(9)]
        col_state_list = [set() for _ in range(9)]
        grid_state_list = [set() for _ in range(9)]

        # - check for each cell
        for row in range(9):
            for col in range(9):
                c = board[row][col]
                if c == '.': continue

                grid_index = (row//3)*3 + col//3

                if c in row_state_list[row]: return False
                if c in col_state_list[col]: return False
                if c in grid_state_list[grid_index]: return False

                row_state_list[row].add(c)
                col_state_list[col].add(c)
                grid_state_list[grid_index].add(c)
        
        return True

おすすめ

転載: www.cnblogs.com/journeyonmyway/p/12690943.html
おすすめ