当前位置: 首页 > article >正文

【LeetCode 刷题】回溯算法(5)-棋盘问题

此博客为《代码随想录》二叉树章节的学习笔记,主要内容为回溯算法棋盘问题相关的题目解析。

文章目录

  • 51. N皇后
  • 37. 解数独
  • 332.重新安排行程

51. N皇后

题目链接

class Solution:
    def solveNQueens(self, n: int) -> List[List[str]]:
        board = [['.' for _ in range(n)] for _ in range(n)]
        res = []

        def check(x: int, y: int) -> bool:
            for i in range(x):
                if board[i][y] == 'Q':  # 列
                    return False
                if y - (x - i) >= 0 and board[i][y-(x-i)] == 'Q':  # 45对角线
                    return False
                if y + (x - i) < n and board[i][y+(x-i)] == 'Q':  # -45对角线
                    return False
            return True
        
        def dfs(row: int) -> None:
            if row == n:
                res.append([''.join(row) for row in board])
                return
            for col in range(n):
                if check(row, col):
                    board[row][col] = 'Q'
                    dfs(row + 1)
                    board[row][col] = '.'
        
        dfs(0)
        return res
  • dfs 函数的参数为行号,即“第 row 行选哪一列放皇后”构成递归树的一层
  • 判断合法性时,不需要判断行是否合法,因为上述解法递归的逻辑即为每一行选择一列去放皇后,所以行约束肯定满足;且判断时只需要判断当前行 x 以上的合法性,因为下面的行还没有放皇后,肯定不会冲突

37. 解数独

题目链接

class Solution:
    def solveSudoku(self, board: List[List[str]]) -> None:
        """
        Do not return anything, modify board in-place instead.
        """
        def check(x: int, y: int, num: str) -> bool:
            for i in range(9):
                if board[i][y] == num:
                    return False
            for i in range(9):
                if board[x][i] == num:
                    return False
            row_s, col_s = x // 3 * 3, y // 3 * 3
            for i in range(3):
                for j in range(3):
                    if board[row_s+i][col_s+j] == num:
                        return False
            return True

        def dfs() -> bool:
            for i in range(9):
                for j in range(9):
                    if board[i][j] == '.':
                        for num in range(1, 10):
                            if check(i, j, str(num)):
                                board[i][j] = str(num)
                                if dfs(): return True
                                board[i][j] = '.'
                        return False
            return True
        
        dfs()
        return
  • 数独的 check 函数需要检查整个棋盘,而非当前行列之前的内容
  • 当找到一个解时,直接返回 True,之前的递归也不再进行回溯;如果当前位置 1-9 全部遍历也没找到解,则返回 False

332.重新安排行程

题目链接

class Solution:
    def findItinerary(self, tickets: List[List[str]]) -> List[str]:
        tickets = sorted(tickets, key=lambda x: (x[0], x[1]))
        graph = {}
        for u, v in tickets:
            if u in graph:
                graph[u].append(v)
            else:
                graph[u] = [v]
        path = ['JFK']
        
        def dfs(u, num):
            if num == 0:
                return True
            if u not in graph or not graph[u]:
                return False
            aims = graph[u].copy()
            for v in aims:
                graph[u].pop(graph[u].index(v))
                path.append(v)
                if dfs(v, num - 1):
                    return True
                path.pop()
                graph[u].append(v)
            return False
    
        dfs("JFK", len(tickets))
        return path
  • dfs 函数的参数分别为:当前站点,以及还有几站到达终点
  • 首先需要将 tickets 转换为有向图的形式,之后遍历当前点所有可能的下一站点列表,每处理一个站点,从原始列表中移除,回溯时再将站点添加回列表
  • 由于最开始按照字典序升序排列,因此一旦找到一条合法行程,即为满足题目要求的字典序最小的行程,递归函数即可返回;如果当前处理的站点不存在合法的下一站,则回溯。

http://www.kler.cn/a/531889.html

相关文章:

  • Spring Boot 2 快速教程:WebFlux处理流程(五)
  • Redis常见命令
  • 编程AI深度实战:给vim装上AI
  • 优化代码性能:利用CPU缓存原理
  • P7497 四方喝彩 Solution
  • 基于Spring Security 6的OAuth2 系列之八 - 授权服务器--Spring Authrization Server的基本原理
  • Linux线程 —— 生产消费模型
  • 存储器知识点3
  • 优选算法的灵动之章:双指针专题(一)
  • 算法设计-0-1背包动态规划(C++)
  • 4.[ISITDTU 2019]EasyPHP
  • Nginx笔记220825
  • 机器学习day7
  • 红黑树的封装
  • 680.验证回文串||
  • 基于“蘑菇书”的强化学习知识点(二):强化学习中基于策略(Policy-Based)和基于价值(Value-Based)方法的区别
  • Debezium Oracle Connector SCN处理优化指南
  • Linux篇——权限
  • 02.03 递归运算
  • 中间件漏洞之CVE-2024-53677
  • C++ 游戏开发:完整指南
  • 浅谈《图解HTTP》
  • Baklib如何在知识管理领域成为领军者与六款产品的综合评析
  • Skyeye 云 VUE 版本 v3.15.6 发布
  • [Java]抽象类
  • 【Three.js+React】教程002:添加lil-gui控制器和加载GLTF模型