[LeetCode in Python] 36 (M) valid sudoku

topic

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

Determine whether a 9x9 Sudoku is valid. You only need to verify whether the number you have entered is valid according to the following rules.

The numbers 1-9 can only appear once per line.
The numbers 1-9 can only appear once in each column.
The numbers 1-9 can only appear once in each 3x3 house separated by a thick solid line.

The picture above is a partially filled effective Sudoku.

The space in the Sudoku part has been filled with numbers, and the blank space is indicated by '.'.

Example 1:

Enter:

[
  ["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"]
]

Output: true

Example 2:

Enter:

[
  ["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"]
]

Output: false

Explanation: Except that the first number in the first line is changed from 5 to 8, the other numbers in the space are the same as in Example 1.
But because there are two 8s in the 3x3 palace in the upper left corner, this Sudoku is invalid.

Explanation:

A valid Sudoku (partially filled) is not necessarily solvable.
You only need to verify whether the number you have filled in is valid according to the above rules.
The given Sudoku sequence contains only the numbers 1-9 and the character '.'.
A given Sudoku is always in the form of 9x9.

Problem-solving ideas

  • The idea of ​​naive is to verify separately by row, column, and nine grids, so that the number of loops is 3 9 * 9.

  • See the code below naive version.

  • After observation, it is found that the numbers that have appeared in rows, columns, and nine-grid grids can actually be stored through collections, so that only a 9 * 9 cycle is needed.

  • See the code below optimized version.

  • In addition, there are other optimization methods, such as not using set (), using an array instead, or even using bits for storage.

Code

# - 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

Guess you like

Origin www.cnblogs.com/journeyonmyway/p/12690943.html