Leetcode_36【有效的数独】

文章目录:

  • 题目
  • 脚本一
  • 脚本一逻辑
  • 脚本二
  • 脚本二逻辑
  • shell解法分享

题目:

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

数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 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 形式的。


脚本一:【用时:152ms】

class Solution:
    def isValidSudoku(self, board: List[List[str]]) -> bool:
        n1,n2,n3,n4 = 0,0,0,0
        num1,num2 = 0,0
        str2,str3,str4 = "","",""
        def test_str(strr):
            n1 = strr.count(".")
            n2 = len(set(strr))
            if (9 - n1) != (n2 -1):
                return("false")
            else:
                return("true")
        #检查每一行
        for i in range(9):
            n1 = board[i].count('.')
            n2 = len(set(board[i]))
            if (9 - n1) != (n2 - 1):
                return(False)
        #检查每一列
        for i in range(9):
            str1 = ""
            for j in range(9):
                str1 += board[j][i]
            result = test_str(str1)
            if result == "false":
                return(False)
            else:
                pass
        #检查小正方形
        for i in range(9):
            for j in range(9):
                if j < 3:
                    str2 += board[i][j]
                elif 2 < j < 6:
                    str3 += board[i][j]
                else:
                    str4 += board[i][j]
            if (i+1) % 3 == 0:
                result1 = test_str(str2)
                result2 = test_str(str3)
                result3 = test_str(str4)
                if result1 == "false" or result2 == "false" or result3 == "false":
                    return(False)
                else:
                    str2 = ""
                    str3 = ""
                    str4 = ""
        return(True)

脚本一逻辑:

  • 第一:如何判断行列和小正方形的数字符合数独的要求,笔者想到的是:通过行、列和小正方形变为字符串,求字符串元素个数n1,然后将字符串转变为集合,再求集合元素个数,再通过比较n1和n2的值即可知道是否符合数独要求【注意对圆点的个数处理】
  • 行直接通过遍历给定列表内容即可判断
  • 列表判断需要使用两个for循环才能进行遍历
  • 小正方形的判断就较费心思,笔者采用的逻辑是:通过是否为3的倍数,获取3行内容,即给定列表的前三个;然后又根据列的数字将每行的元素分给不同的变量,比如123列给变量str1;456列给变量str2;789给变量str3;最后判断str1、str2、str3是否同时符合数独的要求即可
  • 若遇到不符合的,返回false退出即可

脚本二:【用时:100ms】【转载】

class Solution:
    def isValidSudoku(self, board):
        """
        :type board: List[List[str]]
        :rtype: bool
        """
        # init data
        rows = [{} for i in range(9)]
        columns = [{} for i in range(9)]
        boxes = [{} for i in range(9)]

        # validate a board
        for i in range(9):
            for j in range(9):
                num = board[i][j]
                if num != '.':
                    num = int(num)
                    box_index = (i // 3 ) * 3 + j // 3
                    
                    # keep the current cell value
                    rows[i][num] = rows[i].get(num, 0) + 1
                    columns[j][num] = columns[j].get(num, 0) + 1
                    boxes[box_index][num] = boxes[box_index].get(num, 0) + 1
                    
                    # check if this value has been already seen before
                    if rows[i][num] > 1 or columns[j][num] > 1 or boxes[box_index][num] > 1:
                        return False         
        return True

脚本二逻辑:

  • 此脚本逻辑没看懂,目测是运用了数独里面元素之间的某种关联性解决的。有兴趣的朋友可以深入研究一下

 


shell解法分享:

  • 在笔者的CSDN博客中,之前在学习shell的时候也曾使用过shell来处理此题,以下是使用shell处理此题的链接:
  • https://blog.csdn.net/weixin_43428906/article/details/102895947
原文地址:https://www.cnblogs.com/mailong/p/12070763.html