• 回溯算法 | N皇后 | leecode刷题笔记


    跟随carl代码随想录刷题
    语言:python


    51. 困难N 皇后

    题目:按照国际象棋的规则,皇后可以攻击与之处在同一行同一列同一斜线上的棋子。
    n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
    给你一个整数 n返回所有不同的 n 皇后问题 的解决方案
    每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 'Q''.' 分别代表了皇后空位
    👉示例1:
    在这里插入图片描述
    输入:n = 4
    输出:[[“.Q…”,“…Q”,“Q…”,“…Q.”],[“…Q.”,“Q…”,“…Q”,“.Q…”]]
    解释:如上图所示,4 皇后问题存在两个不同的解法。
    👉示例 2:
    输入:n = 1
    输出:[[“Q”]]

    题目分析

    参数:

    • 定义二维数组res来记录最终结果
    • n:棋盘大小
    • row:用来记录遍历到棋盘的第几层了。

    递归终止条件

    • 递归到棋盘最底层,就收集结果并返回
      • if row == n:
        • res.append(chessboard)
        • return
          单层搜索逻辑
    • row控制棋盘的行
    • for 列 in :每一次都从新的一行的其实位置开始搜,从0开始

    验证棋盘是否合法(约束条件)

    • 同一行
    • 同一列
    • 同一斜线

    完整代码如下

    class Solution:
        def solveNQueens(self, n: int) -> List[List[str]]:
            if not n:
                return
            board = [['.']*n for _ in range(n)]  
            # board = [['.', '.', '.', '.'], ['.', '.', '.', '.'], ['.', '.', '.', '.'], ['.', '.', '.', '.']]
    
            res = []
            def isvalid(board, row, col):
                # 判断同一列是否有冲突
                for i in range(len(board)):
                    if board[i][col] == 'Q':
                        return False
                # 判断左上角是否冲突
                i = row - 1
                j = col - 1
                while i >= 0 and j >= 0:
                    if board[i][j] == 'Q':
                        return False
                    i -= 1
                    j -= 1
                # 判断右上角是否有冲突
                i = row - 1
                j = col + 1
                while i >= 0 and j < len(board):
                    if board[i][j] == 'Q':
                        return False
                    i -= 1
                    j += 1
                return True
            
            def backtracking(board, row, n):
                # 如果走到最后一行,说明已经找到一个接
                if row == n:
                    temp_res = []
                    for temp in board:
                        temp_str = ''.join(temp)
                        temp_res.append(temp_str)
                    res.append(temp_res)
                for col in range(n):
                    if not isvalid(board, row, col):
                        continue
                    board[row][col] = 'Q'
                    backtracking(board, row+1, n)
                    board[row][col] = '.'
            
            backtracking(board, 0, n)
            return res
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    37. 困难解数独

    题目:编写一个程序,通过填充空格来解决数独问题。
    数独的解法需 遵循如下规则:
    数字 1-9 在每一行只能出现一次。
    数字 1-9 在每一列只能出现一次。
    数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)
    数独部分空格内已填入了数字,空白格用 ‘.’ 表示。

    题目分析

    待分析

    完整代码如下

    class Solution:
        def solveSudoku(self, board: List[List[str]]) -> None:
            """
            Do not return anything, modify board in-place instead.
            """
            """
            Do not return anything, modify board in-place instead.
            """
            self.backtracking(board)
    
        def backtracking(self, board: List[List[str]]) -> bool:
            # 若有解,返回True;若无解,返回False
            for i in range(len(board)): # 遍历行
                for j in range(len(board[0])):  # 遍历列
                    # 若空格内已有数字,跳过
                    if board[i][j] != '.': continue
                    for k in range(1, 10):  
                        if self.is_valid(i, j, k, board):
                            board[i][j] = str(k)
                            if self.backtracking(board): return True
                            board[i][j] = '.'
                    # 若数字1-9都不能成功填入空格,返回False无解
                    return False
            return True # 有解
    
        def is_valid(self, row: int, col: int, val: int, board: List[List[str]]) -> bool:
            # 判断同一行是否冲突
            for i in range(9):
                if board[row][i] == str(val):
                    return False
            # 判断同一列是否冲突
            for j in range(9):
                if board[j][col] == str(val):
                    return False
            # 判断同一九宫格是否有冲突
            start_row = (row // 3) * 3
            start_col = (col // 3) * 3
            for i in range(start_row, start_row + 3):
                for j in range(start_col, start_col + 3):
                    if board[i][j] == str(val):
                        return False
            return True
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
  • 相关阅读:
    spring mvc的后台代码中如何返回404页面呢?
    【力扣每日一题】2023.9.3 消灭怪物的最大数量
    MySQL学习——在用Connector/NET处理BLOB数据
    现代 C++ 性能飞跃之:移动语义
    基于Java实现的离散数学测试实验
    30天刷题训练(一)
    Java练习题详细解释
    微软 Office 365 如何对接 LDAP 等目录服务?
    嵌入式分享合集106
    亚马逊测评系统是什么,跨境卖家如何通过自己养号来实现快速出单?
  • 原文地址:https://blog.csdn.net/qq_44250700/article/details/126332066