zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    lvs_基础理论
    iptables_表和链(Traversing of tables and chains)
    题解-【集训队作业2018】Simple Tree
    题解-CF559C
    题解-[Violet]天使玩偶/SJY摆棋子
    题解-[POI2014]PRZ-Criminals
    题解-CF961G
    题解-CF1392H
    WorldCreator基础流程
    gstreamer-vaapi 之 README
  • 原文地址:https://www.cnblogs.com/mailong/p/12070763.html
Copyright © 2011-2022 走看看