• leetcode刷题-37解数独


    题目

    编写一个程序,通过已填充的空格来解决数独问题。

    一个数独的解法需遵循如下规则:

    数字 1-9 在每一行只能出现一次。
    数字 1-9 在每一列只能出现一次。
    数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。
    空白格用 '.' 表示。

    思路

    使用暴力破解是不现实的,其需要 9^81次运算。

    因此与数独相同,都需要用到回溯的思想。

    其算法可以简化为:

    1.从头开始选择到一个空白格

    2.选择数字 1-9中的一个,判断是否符合标准(不能重复出现在行,列,3*3方格中)

      2.1 填入数字

      2.2 检查其是否已经找出了数独的解

        2.2.1 若抵达最后一格,获得数独的解

        2.2.2 若没有抵达最后一格,放置下一个数字

        2.2.3 若不存在解,删除当前数字

    实现

    class Solution:
        def solveSudoku(self, board: List[List[str]]) -> None:
            """
            Do not return anything, modify board in-place instead.
            """
            flag = False
            line = [[]for i in range(9)]
            arr = [[]for i in range(9)]
            chunk = [[]for i in range(9)]
    
            def valid_num(num, row, col):
                num_flag = num not in line[row] and num not in arr[col] and num not in chunk[row//3*3+col//3]
                return num_flag
            
            def remove(num, row, col):
                i = line[row].index(num)
                j = arr[col].index(num)
                k = chunk[row//3*3+col//3].index(num)
                del line[row][i]
                del arr[col][j]
                del chunk[row//3*3+col//3][k]
                board[row][col] = '.'
    
            def add(num, row, col):
                line[row].append(num)
                arr[col].append(num)
                chunk[row//3*3+col//3].append(num)
                board[row][col] = num
    
            def check(row, col):
                if row == 8 and col == 8:
                    nonlocal flag
                    flag = True
                else:
                    if col == 8:
                        backtrace(row + 1, 0)
                    else:
                        backtrace(row, col + 1)
    
            def backtrace(row, col):
                if board[row][col] == '.':
                    for m in range(1,10):
                        d= str(m)
                        if valid_num(d, row, col) is True:
                            add(d, row, col)
                            check(row, col)
                            if not flag:
                                remove(d, row, col)
                else:
                    check(row, col)
            
            vex = len(board)
            for i in range(vex):
                for j in range(vex):
                    get = board[i][j]
                    k = i//3*3+j//3
                    if get is not '.':
                        line[i].append(get)
                        arr[j].append(get)
                        chunk[k].append(get)
            # flag = False
            backtrace(0, 0)

    值得注意的是,在check函数中,需要申明nonlocal flag在函数或其他作用域中使用外层(非全局)变量,因为其对flag值进行了修改,否则无法使用。此处不能使用global。

     
  • 相关阅读:
    Map1: iOS开发中定位和地图介绍
    GCD11: 创建计时器
    GCD10: 用GCD构建自己的分派队列
    GCD9: 用GCD将任务分组
    GCD8: 在GCD上让一个任务最多执行一次
    GCD7: 利用GCD延时后执行任务
    GCD6: 在GCD上异步执行非UI相关任务
    GCD5: 用GCD同步执行非UI相关的任务
    回文数
    字符串置换
  • 原文地址:https://www.cnblogs.com/mgdzy/p/13426550.html
Copyright © 2020-2023  润新知