zoukankan      html  css  js  c++  java
  • 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。

     
  • 相关阅读:
    【Qt开发】 V4L2_CAP_VIDEO_OVERLAY与V4L2_CAP_VIDEO_CAPTURE的区别
    【Qt开发】QThread 实用技巧、误区----但文档中没有提到
    【Qt开发】QThread 实用技巧、误区----但文档中没有提到
    【Qt开发】事件循环与线程 二
    【Qt开发】事件循环与线程 二
    【Qt开发】事件循环与线程 一
    【Qt开发】事件循环与线程 一
    【Qt开发】QThread介绍
    【Qt开发】QThread介绍
    【Linux开发】如何查看Linux kernel的内置模块驱动列表和进程ID
  • 原文地址:https://www.cnblogs.com/mgdzy/p/13426550.html
Copyright © 2011-2022 走看看